安卓:如何更改每个元素的可绘制资源的颜色?



Edit 4/5:我的getViewAt函数现在是这个,仍然没有效果发生

override fun getViewAt(position: Int): RemoteViews {
val v = (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
.inflate(R.layout.widget_item, null)
.findViewById<ProgressBar>(R.id.progressBar)
.apply {
this.progressBackgroundTintList = ColorStateList.valueOf(0x00ff00)
this.progressTintList = ColorStateList.valueOf(0xffff00)
this.max = 100
this.progress = 0
this.isIndeterminate = false
this.progressDrawable = context.resources.getDrawable(R.drawable.circle_progress_bar, null)
}
val layer = context.resources.getDrawable(R.drawable.circle_progress_bar, null) as LayerDrawable
layer.getDrawable(0).setColorFilter(0x03a9f4, android.graphics.PorterDuff.Mode.SRC_IN)
layer.getDrawable(1).setColorFilter(0x8bc34a, android.graphics.PorterDuff.Mode.SRC_IN)
View.inflate(context, R.layout.widget_item, null)
.findViewById<ProgressBar>(R.id.progressBar)
.progressDrawable = layer

val r = RemoteViews(context.packageName, R.layout.widget_item).apply {
val event = MiniModel.events[position]
//          setProgressBar(
//                  R.id.progressBar,
//                  event.totalDuration.toInt(unit = DurationUnit.SECONDS),
//                  event.timeRemaining.toInt(unit = DurationUnit.SECONDS),
//                  false
//          )
reapply(context, v)
setTextViewText(R.id.item_text, event.title)
setTextViewText(R.id.details_text, if (event.isOver) "Event Complete" else "in " + event.timeRemaining.asPrettyString)
}
View.inflate(context, r.layoutId, null).findViewById<ProgressBar>(R.id.progressBar)
.apply {
this.progressBackgroundTintList = ColorStateList.valueOf(0x00ff00)
this.progressTintList = ColorStateList.valueOf(0xffff00)
this.max = 100
this.progress = 0
this.isIndeterminate = false
this.progressDrawable = context.resources.getDrawable(R.drawable.circle_progress_bar, null)
}
return r
}

我正在制作一个Android应用程序小部件,它是一个包含n行的列表视图。在每一行中,我都有一个自定义的圆形进度指示器,它有两种颜色;一个用于背景,一个用于前景。进度指示器的颜色对于每行都不同,但基于相同的可绘制对象资源。

我的问题是,在设置/更新我的小部件时,如何更改每行中的进度指示器颜色?另一个挑战是我无法访问findViewById,因为我使用RemoteViewsFactory构建我的小部件。

@drawable/circle_progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape
android:innerRadiusRatio="1000"
android:shape="ring"
android:thicknessRatio="10"
android:useLevel="false">
<solid android:color="#0000ff" />  <!-- I want this to be set programatically per widget row -->
</shape>
</item>
<item android:id="@android:id/progress">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270">
<shape
android:innerRadiusRatio="1000"
android:shape="ring"
android:thicknessRatio="10"
android:useLevel="true">
<solid android:color="#ff0000" />  <!-- this too -->
</shape>
</rotate>
</item>
</layer-list>

@layout/widget_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/shape"
android:gravity="center_vertical">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:scaleX="2"
android:scaleY="2"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_weight="0"
android:indeterminate="false"
android:max="100"
android:progress="25"
android:progressDrawable="@drawable/circle_progress_bar" />
</LinearLayout>

EventWidgetService.kt

class EventWidgetService : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory =
EventRemoteViewsFactory(this.applicationContext, intent)
}
class EventRemoteViewsFactory(private val context: Context, intent: Intent) : RemoteViewsService.RemoteViewsFactory {
private val prefsName = "FlutterSharedPreferences"
override fun onCreate() {
MiniModel.initialize(context.getSharedPreferences(prefsName, Context.MODE_PRIVATE))
}
override fun getLoadingView(): RemoteViews = RemoteViews(context.packageName, R.id.emptyView)
override fun getItemId(position: Int): Long = position.toLong()
override fun onDataSetChanged() {
}
override fun hasStableIds(): Boolean = true
@ExperimentalTime
override fun getViewAt(position: Int): RemoteViews {
return RemoteViews(context.packageName, R.layout.widget_item).apply {
val event = MiniModel.events[position]
setProgressBar(
R.id.progressBar,
(event.end.epochSecond - event.start.epochSecond).toInt(),
event.secondsRemaining.toInt(unit = TimeUnit.SECONDS),
false
)
setTextViewText(R.id.item_text, event.title)
setTextViewText(R.id.details_text, if (event.isOver) "Event Complete" else "in " + event.secondsRemaining.asPrettyString)
}
}
override fun getCount(): Int = MiniModel.events.count()
override fun getViewTypeCount(): Int = 1
override fun onDestroy() {
}
}

编辑 1/2 摘要反射不起作用

编辑3:在我的getViewAt(Int): RemoteViews函数中,我还尝试添加

View.inflate(context, R.layout.widget_item, null).findViewById<ProgressBar(R.id.progressBar).apply {
progressBackgroundTintList = ColorStateList.valueOf(0x00ff00)
progressTintList = ColorStateList.valueOf(0xffff00)
}

但是,这没有任何效果。

使用 RemoteViewsetProgressBackgroundTintList方法更改蓝色,setProgressTintList更改红色。

保持相同的 xml 并在运行时使用以下代码更改颜色。

val layerDrawable = resources.getDrawable(R.drawable.circle_progress_bar) as LayerDrawable

layerDrawable.getDrawable(0).setColorFilter(Color.parseColor("#FF03A9F4"), android.graphics.PorterDuff.Mode.SRC_IN)layerDrawable.getDrawable(1).setColorFilter(Color.parseColor("#FF8BC34A"), android.graphics.PorterDuff.Mode.SRC_IN)

progressBar.progressDrawable = layerDrawable

最新更新