如何更改小部件中图像的背景颜色 android

How to change background color at image in widget android

我在更改小部件中图像的背景颜色时遇到问题。 现在我是这样使用的:

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, class 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; 
} 

您可以检查新方法的工作原理以及需要哪些参数,然后在您的项目中加入类似以下内容:

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()
}

另一个解决方案可能是:

据我所知,方法 setDrawableParameters(..) 是隐藏的,因此不能以这种方式使用,我想这不是解决您问题的最佳方案。它看起来像是一个 hacky 解决方案,但一旦他们更改它或者一旦它不再以您认为的方式得到支持,它实际上会变得更糟。

让我们从头开始,您想更改小部件中图像的背景颜色,更准确地说,在 RemoteView 中,可能您可以将 drawable 转换为 bitmap 然后调用 RemoteViews.setImageBitmap()

这是Convert a drawable into a bitmap

的方法

更新:作者刚刚找到的另一个解决方案是

Another solution that worked for me is to have the image source in the xml layout android:src="@mipmap/myImage" and in code remoteViews.setInt(R.id.myImageView,"setColorFilter", myColor);

这里作者回答:

另一个对我有用的解决方案是在 xml 布局 android:src="@mipmap/myImage" 和代码 remoteViews.setInt(R.id.myImageView,"setColorFilter", myColor);

中使用图像源