在任何活动的普通Android代码中,我都可以使用
控制可绘制背景的颜色Drawable d = findViewById(R.id.button_highlight).getBackground();
PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
d.setColorFilter(filter);
我想知道如何在WidgetProvider中利用它来动态更改我的元素背景可绘制的背景颜色
从我的AppWidgetProvider实例中我想打电话:
int color2 = settings.getInt("secondary_color", R.color.main_alt);
// following won't work because a <Button> has no method "setColorFilter"
remoteViews.setInt(R.id.button_highlight,"setColorFilter",color2);
我的带有ID为R.id.highlight的按钮的button_bg.xml是这样的:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<corners android:topRightRadius="5dp" android:bottomRightRadius="5dp"/>
<solid android:color="@color/main_alt"/>
<padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp"/>
</shape>
</item>
<item>
<shape>
<corners android:topRightRadius="5dp" android:bottomRightRadius="5dp"/>
<solid android:color="@color/main"/>
<padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp"/>
</shape>
</item>
</selector>
有任何变通方法吗?我错过了什么吗?如何更改背景可绘制的颜色?我正在考虑继承Button并实现自定义方法来设置颜色,但我首先想知道是否有更常见或更简单的方法..
答案 0 :(得分:2)
setColorFilter(int color,PorterDuff.Mode模式)没有@RemotableViewMethod注释,因此无法在RemoteViews中使用。
我最好的选择是将drawable转换为位图,然后使用RemoteViews.setImageBitmap():http://developer.android.com/reference/android/widget/RemoteViews.html#setImageViewBitmap(int, android.graphics.Bitmap) 我实际上没有测试它,但它值得尝试。我发现有些方法在远程视图中不起作用,即使它们具有@RemotableViewMethod注释,因此它可能会也可能不起作用。
您可以在SO上找到有关如何将Drawable转换为位图的答案,例如:这里: https://stackoverflow.com/a/9390776/534471
答案 1 :(得分:1)
昨晚我需要这样做! 但在我读了RemoteViews.java后,我发现我应该用PorterDuff添加setColorFilter
从原版android RemotView.java看这里
/**
* @hide
* Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
* {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
* and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
* view.
* <p>
* You can omit specific calls by marking their values with null or -1.
*
* @param viewId The id of the view that contains the target
* {@link Drawable}
* @param targetBackground If true, apply these parameters to the
* {@link Drawable} returned by
* {@link android.view.View#getBackground()}. Otherwise, assume
* the target view is an {@link ImageView} and apply them to
* {@link ImageView#getDrawable()}.
* @param alpha Specify an alpha value for the drawable, or -1 to leave
* unchanged.
* @param colorFilter Specify a color for a
* {@link android.graphics.ColorFilter} for this drawable, or -1
* to leave unchanged.
* @param mode Specify a PorterDuff mode for this drawable, or null to leave
* unchanged.
* @param level Specify the level for the drawable, or -1 to leave
* unchanged.
*/
public void setDrawableParameters(int viewId, boolean targetBackground, int alpha,
int colorFilter, PorterDuff.Mode mode, int level) {
addAction(new SetDrawableParameters(viewId, targetBackground, alpha,
colorFilter, mode, level));
}
那么你可以像我一样使用它,例如:
contentView.setDrawableParameters(R.id.right_icon, false, -1, mBiftorIconColor, android.graphics.PorterDuff.Mode.MULTIPLY, -1);
我知道回答你的问题为时已晚,但也许很多人都会需要它。
祝你好运 阿明。答案 2 :(得分:1)
id喜欢根据@bitfor的答案添加内容。
由于该方法是用@hide注释的,因此无法直接调用,因此必须通过反射调用该方法:
int id = R.id.button1 //(the button in widget)
RemoteViews views = ....
int textcolor = .......
int backgroundcolor = .....
views.setTextViewText(id, "myButtontext");
views.setTextColor(id, textcolor);
Class c = Class.forName("android.widget.RemoteViews");
Method m = c.getMethod("setDrawableParameters", new Class[] {int.class, boolean.class, int.class, int.class, PorterDuff.Mode.class, int.class});
m.invoke(views, new Object[]{id, true, -1, backgroundcolor, android.graphics.PorterDuff.Mode.OVERLAY, -1});
希望它有所帮助:)经过测试并确认在4.4和5.0上工作
答案 3 :(得分:1)
您应该使用带有match_parent参数的ImageView puted或Relative布局创建背景。因此,您可以在代码中更改颜色和透明度dinamicaly。 我的小部件布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="@dimen/widget_margin"
android:orientation="vertical"
android:gravity="center"
android:baselineAligned="false"
android:id="@+id/widget_layout">
<ImageView
android:id="@+id/widget_background_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/layout_bg"
android:contentDescription="@string/background"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
<TextView
android:id="@+id/widget_text"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:contentDescription="@string/appwidget_text"
android:text="@string/widget_default_name"
android:textColor="#fbff00"
android:textSize="12sp"
android:textStyle="bold"
android:allowUndo="false"
android:clickable="true"
android:gravity="bottom|center"
android:layout_weight="1"/>
</RelativeLayout>
在drawables中创建自定义形状文件 layout_bg.xml :
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="10dip"/>
<padding android:left="8dip" android:top="8dip" android:right="8dip" android:bottom="8dip" />
</shape>
现在,在窗口小部件更新侦听器中,您可以按代码设置任何颜色:
remoteViews.setInt(R.id.widget_background_image, "setColorFilter", backColor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
remoteViews.setInt(R.id.widget_background_image,"setImageAlpha",Color.alpha(backColor));
} else {
remoteViews.setInt(R.id.widget_background_image, setAlpha",Color.alpha(backColor));
}