简体   繁体   English

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

[英]How to change background color at image in widget android

I have a problem with change background color at image in widget. 我在小部件中更改图像的背景色时遇到问题。 Right now i'm using like this: 现在我正在使用这样的:

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

Everything works perfect, until i tested on android 9, here i receive an error: 一切正常,直到我在android 9上测试,在这里我收到一个错误:

java.lang.NoSuchMethodException: setDrawableParameters [int, boolean, int, int, class android.graphics.PorterDuff$Mode, int] java.lang.NoSuchMethodException:setDrawableParameters [int,boolean,int,int,类android.graphics.PorterDuff $ Mode,int]

Do you have any idea how can i make it work on android 9 also? 你有什么想法我也可以使其在android 9上工作吗? Thanks. 谢谢。

setDrawableParameters(..) is called setDrawableTint(..) in Android 9.0 . setDrawableParameters(..)在Android 9.0中称为setDrawableTint(..)

Here is the source code of the new method setDrawableTint(..) available in Android 9.0, I guess it does the same job as setDrawableParameters(..) in previous version of Android but you have to try it out in your project. 这是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; 
} 

You could check how the new method works and what parameters needs and then have in your project something like: 您可以检查新方法的工作方式以及需要哪些参数,然后在项目中添加以下内容:

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

Another solution could be: 另一个解决方案可能是:

As I see the method setDrawableParameters(..) is hidden, so it is not meant to be used in this way, I guess it won't be the optimal solution to solve your problem. 正如我看到的setDrawableParameters(..)方法是隐藏的,因此不应以这种方式使用它,我想它不是解决您问题的最佳解决方案。 It looks like a hacky solution, but it can actually get worst once they change it or once it won't be supported in the way you thought it works. 它看起来像一个骇人听闻的解决方案,但是一旦他们更改了它,或者一旦您认为它无法正常运行,它就会变得更糟。

Let's start from the beginning, you want to change the background color of an image in a widget, in a RemoteView more precisely, probably you could convert the drawable into a bitmap and then call RemoteViews.setImageBitmap() 让我们从头开始,您想更改小部件中图像的背景颜色,更确切地说,在RemoteView ,可能可以将drawable转换为bitmap ,然后调用RemoteViews.setImageBitmap()

Here is how to Convert a drawable into a bitmap 这是将可绘制对象转换为位图的方法

UPDATE: Another solution that the author just found was 更新:作者刚刚发现的另一个解决方案是

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)中设置图像源;

Here the author answer: https://stackoverflow.com/a/55123126/3564632 这是作者的答案: https : //stackoverflow.com/a/55123126/3564632

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM