【问题标题】:Change drawable color programmatically以编程方式更改可绘制颜色
【发布时间】:2012-07-07 18:10:39
【问题描述】:

我正在尝试通过代码更改白色标记图像的颜色。我读过下面的代码应该改变颜色,但我的标记仍然是白色的。

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

我错过了什么吗?有没有其他方法可以更改我 res 文件夹中的可绘制对象的颜色?

【问题讨论】:

  • 接受的答案对我不起作用..使用了这个How to Answer[1],[1]:stackoverflow.com/questions/5940825/…
  • 我认为这里的所有答案都会改变背景颜色,但不会改变图像的颜色。我说的对吗?谁能告诉我?我在这里尝试了所有解决方案以及关于 stackoverflow 的相同问题,但在可能的情况下它们只会改变背景颜色。所以我认为,我们只能更改背景颜色,但不能更改图像颜色。我说的对吗?

标签: android


【解决方案1】:

试试这个:

Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.my_drawable); 
Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(wrappedDrawable, Color.RED);    

使用DrawableCompat 很重要,因为它在 API 22 和更早版本的设备上提供向后兼容性和错误修复。

【讨论】:

  • 嗯,颜色保持白色。它可能与可能导致问题的 hello mapview OverlayItems 类有关吗?它是我 res 文件夹中的常规可绘制对象,没什么特别的......
  • @ρяσѕρєяK 你太棒了。很有帮助
  • 如果您希望 PorterDuff.Mode.SRC_IN 使用更广泛的源颜色,您可能更喜欢它。
  • PorterDuffColorFilter 构造函数采用 ARGB 颜色格式
  • 用#mutate() 改变drawable 以避免与任何其他drawable 共享它的状态会很有趣,否则如果你重复使用drawable 可能会有错误的颜色。
【解决方案2】:

您可能想试试Mode.LIGHTEN 或Mode.DARKEN。 Android Javadocs 很难解释 PorterDuff 模式的作用。您可以在这里查看它们:PorterDuff | Android

我建议在 Mozilla 的网站 here. 上查看 Compositing(它们没有 android 提供的所有模式,但它们有很多)

【讨论】:

    【解决方案3】:

    您可以尝试使用 ColorMatrixColorFilter,因为您的主色是白色:

    // Assuming "color" is your target color
    float r = Color.red(color) / 255f;
    float g = Color.green(color) / 255f;
    float b = Color.blue(color) / 255f;
    
    ColorMatrix cm = new ColorMatrix(new float[] {
            // Change red channel
            r, 0, 0, 0, 0,
            // Change green channel
            0, g, 0, 0, 0,
            // Change blue channel
            0, 0, b, 0, 0,
            // Keep alpha channel
            0, 0, 0, 1, 0,
    });
    ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
    myDrawable.setColorFilter(cf);
    

    【讨论】:

      【解决方案4】:

      在 Lollipop 上执行此操作的另一种方法,android 5.+ 是在可绘制的位图上设置色调,如下所示:

      <?xml version="1.0" encoding="utf-8"?>
      <bitmap
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:src="@drawable/ic_back"
          android:tint="@color/red_tint"/>
      

      如果您想在可绘制对象上使用的颜色数量有限,这将适用于您。 Check out my blog post for more information.

      【讨论】:

      • 不错!顺便说一句,这似乎在棒棒糖之前也可以正常工作。 (刚刚使用minSdkVersion 16 和 Android 4.1.1 设备对此进行了测试。)
      • 以这种方式创建位图时,它不会像使用android:background="..." 时那样拉伸以适应布局。很奇怪!
      • 我认为那是因为您没有在这里创建九个补丁。
      • 抱歉此页面不存在=(
      • @Jonik 您提供的问题中的答案无关紧要。这个问题是询问如何改变 Drawable 的颜色,而不是 ImageView。
      【解决方案5】:

      您可能需要在可绘制对象上调用 mutate() 否则所有图标都会受到影响。

      Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_my_icon).mutate();
      TypedValue typedValue = new TypedValue();
      getContext().getTheme().resolveAttribute(R.attr.colorIcon, typedValue, true);
      icon.setColorFilter(typedValue.data, PorterDuff.Mode.SRC_ATOP);
      

      【讨论】:

      • 真正让您的答案令人难以置信的是mutate(),这正是我正在寻找的。谢谢。
      【解决方案6】:

      这就是我所做的:

      public static Drawable changeDrawableColor(int drawableRes, int colorRes, Context context) {
          //Convert drawable res to bitmap
          final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableRes);
          final Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                  bitmap.getWidth() - 1, bitmap.getHeight() - 1);
          final Paint p = new Paint();
          final Canvas canvas = new Canvas(resultBitmap);
          canvas.drawBitmap(resultBitmap, 0, 0, p);
      
          //Create new drawable based on bitmap
          final Drawable drawable = new BitmapDrawable(context.getResources(), resultBitmap);
          drawable.setColorFilter(new
                  PorterDuffColorFilter(context.getResources().getColor(colorRes), PorterDuff.Mode.MULTIPLY));
          return drawable;
      }
      

      【讨论】:

        【解决方案7】:

        你可以试试这个 svg vector drawable

        DrawableCompat.setTint(
            DrawableCompat.wrap(myImageView.getDrawable()),
            ContextCompat.getColor(context, R.color.another_nice_color)
        );
        

        【讨论】:

        • 我见过的 svg 的最佳方式。
        • 更喜欢这个而不是接受的答案,虽然两者都可以工作,但是有了这个我不必担心要设置什么可绘制对象,我只是得到一个已经存在的,它也是向后兼容的,太好了!
        • 什么都没有用时的最佳答案 iot 像魅力一样工作!非常感谢!注意:它也适用于您的 imageView/AppCompatImageView 中有 xml drawable
        • 如何以编程方式删除它?
        • @HardikJoshi 文档说:要清除色调,请将null 传递给Drawable#setTintList(ColorStateList)
        【解决方案8】:

        我编写了一个通用函数,您可以在其中传递上下文,图标是 id 可绘制/mipmap 图像图标和该图标所需的新颜色。

        这个函数返回一个drawable。

        public static Drawable changeDrawableColor(Context context,int icon, int newColor) {
            Drawable mDrawable = ContextCompat.getDrawable(context, icon).mutate(); 
            mDrawable.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_IN)); 
            return mDrawable;
        } 
        
        changeDrawableColor(getContext(),R.mipmap.ic_action_tune, Color.WHITE);
        

        【讨论】:

          【解决方案9】:

          与接受的答案相同,但更简单的便捷方法:

          val myDrawable = ContextCompat.getDrawable(context, R.drawable.my_drawable)
          myDrawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN)
          setCompoundDrawablesWithIntrinsicBounds(myDrawable, null, null, null)
          

          注意,这里的代码是 Kotlin。

          【讨论】:

            【解决方案10】:

            这对我有用。确保将“ff”放在 0x 和颜色代码之间。像这样 0xff2196F3

            Drawable mDrawable = ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_vector_home);
                                mDrawable.setColorFilter(new
                                        PorterDuffColorFilter(0xff2196F3,PorterDuff.Mode.SRC_IN));
            

            【讨论】:

            • 嗨@Bek 欢迎来到stackoverflow。如果这对您有用,那么包含一个带有最少解决方案的 jsfiddle 会非常有帮助。这将有助于发布问题的人正确理解。
            【解决方案11】:

            你可以试试这个ImageView。使用setColorFilter()。

            imageView.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));
            

            【讨论】:

              【解决方案12】:

              语法

              "your image name".setColorFilter("your context".getResources().getColor("color name"));
              

              示例

              myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));
              

              【讨论】:

                【解决方案13】:

                使用这个:对于java

                view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_OVER)
                

                对于科特林

                view.background.setColorFilter(Color.parseColor("#343434"),PorterDuff.Mode.SRC_OVER)
                

                如果您的背景有圆角等,您可以使用 PorterDuff.Mode.SRC_ATOP。

                【讨论】:

                  【解决方案14】:

                  像这样创建方法:

                  //CHANGE ICON COLOR
                  private void changeIconColor(Context context ,int drawable){
                      Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, drawable);
                      assert unwrappedDrawable != null;
                      Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
                      DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.colorAccent));
                  }
                  

                  并像它一样使用它:

                      changeIconColor(this,R.drawable.ic_home);
                  

                  【讨论】:

                    【解决方案15】:

                    最简单的方法:

                    imageView.setColorFilter(Color.rgb(r, g b));
                    

                    或

                    imageView.setColorFilter(Color.argb(a, r, g, b));
                    

                    a, r, g, b : 颜色 argb 值。

                    【讨论】:

                    • 这只有在 OP 使用 imageViews 而不是 drawables 时才有效。
                    【解决方案16】:

                    对于那些使用 Kotlin 的人一个简单的扩展功能:

                    fun Drawable.tint(context: Context,  @ColorRes color: Int) {
                        DrawableCompat.setTint(this, context.resources.getColor(color, context.theme))
                    }
                    

                    然后简单地做

                    background.tint(context, R.color.colorPrimary)
                    

                    【讨论】:

                      【解决方案17】:

                      您可以通过这种方式更改您的可绘制颜色:

                      background = view.findViewById(R.id.background)
                      
                      val uDrawable = AppCompatResources.getDrawable(view.context, R.drawable.background)
                      uDrawable?.let {
                            val wDrawable = DrawableCompat.wrap(it)
                            DrawableCompat.setTint(wDrawable, ContextCompat.getColor(view.context, 
                                                                            color /*specify your int color code*/))
                            background.background = wDrawable
                      }
                      

                      【讨论】:

                        【解决方案18】:

                        长话短说:

                        public void changeDrawableColor(Drawable drawable,int color){
                            drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                        }
                        

                        public Drawable getColoredDrawable(@DrawableRes int resid,int color){
                            Drawable drawable= ContextCompat.getDrawable(context, resid).mutate();
                            drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                            return drawable;
                        }
                        

                        【讨论】:

                          【解决方案19】:

                          SDK >= 21 一行 myIconImageView.getDrawable().setTint(getResources().getColor(myColor))

                          【讨论】:

                            猜你喜欢
                            • 2014-03-26
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2021-07-04
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多