如何在android小部件中更改图像的背景色
我在小部件中更改图像的背景色时遇到问题。 现在我用的是这样的:如何在android小部件中更改图像的背景色,android,widget,background-image,Android,Widget,Background Image,我在小部件中更改图像的背景色时遇到问题。 现在我用的是这样的: try { Class c = Class.forName("android.widget.RemoteViews"); Method m = c.getMethod("setDrawableParameters", int.class, boolean.class, int.class, int.class, PorterDuff.Mode.class, int.class); m.
try {
Class c = Class.forName("android.widget.RemoteViews");
Method m = c.getMethod("setDrawableParameters", int.class, boolean.class, int.class, int.class, PorterDuff.Mode.class, int.class);
m.invoke(remoteViews, R.id.myImage, true, -1, Color.HSVToColor(color), PorterDuff.Mode.SRC_OVER, -1);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
一切都很完美,直到我在android 9上测试,这里我收到一个错误:
java.lang.NoSuchMethodException:setDrawableParameters[int,boolean,
int,int,类android.graphics.PorterDuff$Mode,int]
你知道我怎样才能让它也在android 9上工作吗?
谢谢。
setDrawableParameters(..)
在Android 9.0中被称为setDrawableTint(..)
以下是Android 9.0中提供的新方法setDrawableTint(..)
的源代码,我想它与Android早期版本中的setDrawableParameters(..)
的功能相同,但您必须在项目中试用
/**
* Equivalent to calling
* {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
* on the {@link Drawable} of a given view.
* <p>
* The operation will be performed on the {@link Drawable} returned by the
* target {@link View#getBackground()} by default. If targetBackground is false,
* we assume the target is an {@link ImageView} and try applying the operations
* to {@link ImageView#getDrawable()}.
* <p>
*/
private class SetDrawableTint extends Action {
SetDrawableTint(int id, boolean targetBackground,
int colorFilter, @NonNull PorterDuff.Mode mode) {
this.viewId = id;
this.targetBackground = targetBackground;
this.colorFilter = colorFilter;
this.filterMode = mode;
}
SetDrawableTint(Parcel parcel) {
viewId = parcel.readInt();
targetBackground = parcel.readInt() != 0;
colorFilter = parcel.readInt();
filterMode = PorterDuff.intToMode(parcel.readInt());
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(viewId);
dest.writeInt(targetBackground ? 1 : 0);
dest.writeInt(colorFilter);
dest.writeInt(PorterDuff.modeToInt(filterMode));
}
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
final View target = root.findViewById(viewId);
if (target == null) return;
// Pick the correct drawable to modify for this view
Drawable targetDrawable = null;
if (targetBackground) {
targetDrawable = target.getBackground();
} else if (target instanceof ImageView) {
ImageView imageView = (ImageView) target;
targetDrawable = imageView.getDrawable();
}
if (targetDrawable != null) {
targetDrawable.mutate().setColorFilter(colorFilter, filterMode);
}
}
@Override
public int getActionTag() {
return SET_DRAWABLE_TINT_TAG;
}
boolean targetBackground;
int colorFilter;
PorterDuff.Mode filterMode;
}
/**
*相当于呼叫
*{@link Drawable#setColorFilter(int,android.graphics.PorterDuff.Mode)},
*在给定视图的{@link Drawable}上。
*
*该操作将在返回的{@link Drawable}上执行
*默认情况下,目标为{@link View#getBackground()}。如果targetBackground为false,
*我们假设目标是{@link ImageView},并尝试应用这些操作
*到{@link ImageView#getDrawable()}。
*
*/
私有类SetDrawableTint扩展操作{
SetDrawableTint(整数id,布尔targetBackground,
int colorFilter,@NonNull PorterDuff.Mode模式){
this.viewId=id;
this.targetBackground=targetBackground;
this.colorFilter=colorFilter;
this.filterMode=模式;
}
SetDrawableTint(包裹){
viewId=parcel.readInt();
targetBackground=parcel.readInt()!=0;
colorFilter=parcel.readInt();
filterMode=PorterDuff.intToMode(parcel.readInt());
}
公共无效writeToParcel(Parcel dest,int标志){
目标写入(视图ID);
目标写入(targetBackground?1:0);
目的写入(颜色过滤器);
目的写入(PorterDuff.modeToInt(filterMode));
}
@凌驾
public void apply(视图根、视图组根父、OnClickHandler处理程序){
最终视图目标=root.findviewbyd(viewId);
if(target==null)返回;
//为此视图选择要修改的正确绘图
Drawable targetDrawable=null;
if(targetBackground){
targetDrawable=target.getBackground();
}如果(ImageView的目标实例){
ImageView ImageView=(ImageView)目标;
targetDrawable=imageView.getDrawable();
}
如果(targetDrawable!=null){
targetDrawable.mutate().setColorFilter(colorFilter,filterMode);
}
}
@凌驾
public int getActionTag(){
返回设置\u可绘制\u着色\u标签;
}
布尔目标背景;
int彩色滤光片;
PorterDuff.Mode filterMode;
}
您可以检查新方法的工作方式以及需要哪些参数,然后在项目中包含如下内容:
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P){
// Your actual implementation with "setDrawableParameters"
changeImageBackgroundColorBeforeAndroidPIE()
} else{
// Your new implementation with "setDrawableTint"
changeImageBackgroundColorAndroidPIEAndLater()
}
if(android.os.Build.VERSION.SDK\u INT
另一个解决方案可以是:
正如我看到的方法setDrawableParameters(..)
是隐藏的,因此它不打算以这种方式使用,我想它不会是解决问题的最佳解决方案。它看起来像一个黑客解决方案,但一旦他们改变它,或者一旦它无法以您认为有效的方式得到支持,它实际上可能会变得最糟糕
让我们从头开始,您想要更改小部件中图像的背景色,在RemoteView
中更准确地说,您可以将可绘制的
转换为位图
,然后调用
以下是如何
更新:作者刚刚找到的另一个解决方案是
另一个对我有效的解决方案是在 xml布局android:src=“@mipmap/myImage”和代码 setInt(R.id.myImageView,“setColorFilter”,myColor)
作者的回答是:另一个对我有效的解决方案是将图像源放在xml布局
android:src=“@mipmap/myImage”
和coderemoteview.setInt(R.id.myImageView,“setColorFilter”,myColor)中代码>我已经尝试了解决方案1:Drawable-Drawable=ContextCompat.getDrawable(context,R.mipmap.image);drawable.setColorFilter(Color.HSVToColor(mycolor),PorterDuff.Mode.SRC_;位图位图=drawableToBitmap(drawable);RemoteView.setImageViewBitmap(R.id.myimageview,位图);
,但不起作用。解决方案2它起作用了,非常感谢。尝试Android 9中提供的新方法。我更新了我的答案,以更好地匹配您问题的上下文和范围第一个解决方案有效…但我收到了屏幕上弹出一条消息:检测到API兼容性问题
若要解决此问题,我必须将targetSdkVersion修改为28,但之后背景不变,我收到错误:java.lang.NoSuchMethodException:setDrawableTint[int,boolean,int,class android.graphics.PorterDuff$Mode]
弹出窗口之所以出现,是因为您试图访问深灰色列表API方法中的方法是的,您是对的……看起来没有办法更改小部件的背景图像颜色……我喜欢它!@Bogdan感谢您的贡献!我添加了您的答案,并在我的accep中提到了您