【问题标题】:DrawableCompat setTint not working on API 19DrawableCompat setTint 不适用于 API 19
【发布时间】:2016-08-12 10:19:55
【问题描述】:

我正在使用 DrawableCompat 为 drawable 着色,如下所示,着色似乎不适用于 API 19。我正在使用支持 lib 版本 23.3.0

Drawable drawable = textView.getCompoundDrawables()[drawablePosition];
if (drawable != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            drawable.setTint(color);
        } else {
            DrawableCompat.setTint(DrawableCompat.wrap(drawable), color);
        }
    }

【问题讨论】:

    标签: android android-support-library android-drawable


    【解决方案1】:

    我遇到了同样的问题。我将https://stackoverflow.com/a/30928051 中的帖子合并,并尝试了 API 17、19、21、22、23 和 N Preview 3 与 SupportLib 23.4.0 以找到解决方案。

    即使提到,compat-class 将对棒棒糖之前的设备使用过滤器(请参阅https://stackoverflow.com/a/27812472/2170109),但它不起作用。

    现在,我自己检查 API 并使用以下代码,该代码适用于所有经过测试的 API(适用于 17 及以上)。

        // https://stackoverflow.com/a/30928051/2170109
        Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
        image.setImageDrawable(drawable);
    
        /*
         * need to use the filter | https://stackoverflow.com/a/30880522/2170109
         * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
         */
        int color = ContextCompat.getColor(context, R.color.yourcolor);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            DrawableCompat.setTint(drawable, color);
    
        } else {
            drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
        }
    

    【讨论】:

    • 终于有一些对我有用的棒棒糖了。非常感谢您的分享。
    • 它在 Lollipop (API 21) 上对我不起作用。我不得不将最低版本更改为 API 22 (Build.VERSION_CODES.LOLLIPOP_MR1)。
    • 结合 hardysim 和 @Eselfar 的答案对我有用。
    【解决方案2】:

    使用 AppCompat 支持库在 API 15-25 上工作(在 24.1.1 及更高版本上测试)。

    public static Drawable getTintedDrawable(@NonNull final Context context,
                                             @DrawableRes int drawableRes, @ColorRes int colorRes) {
        Drawable d = ContextCompat.getDrawable(context, drawableRes);
        d = DrawableCompat.wrap(d);
        DrawableCompat.setTint(d.mutate(), ContextCompat.getColor(context, colorRes));
        return d;
    }
    

    【讨论】:

    • 我尝试了支持库 24.2.1,但不幸的是它不适用于 API 19。我继续使用@hardysim 的解决方案。
    • 支持库 25.1.1 在 API 19/21/25 上为我工作
    • 就我而言,只有mutate() 就足够了。
    • @Eselfar 这行得通,但是请注意,您必须添加行 d = DrawableCompat。包装(d);这包装了可绘制对象,以便在设置色调时对其进行变异
    • 它只适用于添加DrawableCompat.wrap(Drawable)。请问以上情况.mutate()有什么用?
    【解决方案3】:

    我认为包装你的drawable之后,你需要在它上面调用mutate()。看到这个:https://stackoverflow.com/a/30928051/3032209

    【讨论】:

      【解决方案4】:

      基于@localhost答案

      Drawable d = DrawableCompat.wrap(ContextCompat.getDrawable(this, R.drawable.ic_rate));
      DrawableCompat.setTint(d, Color.parseColor("#AAAAAA"));
      l.setLogo(d);
      

      我在 API 19>25 上试过,效果很好

      【讨论】:

        【解决方案5】:

        我制作了以下辅助方法来设置带有色调的可绘制对象,它至少从 API 级别 16 到 x 都可以工作。颜色是主题色,因此通过属性解析。

          public static Drawable getTintedDrawable(int drawableResourceId, int colorAttribute) {
            YourApplication = YourApplication.getInstance();
            Drawable drawable = ContextCompat.getDrawable(application, drawableResourceId);
            drawable = DrawableCompat.wrap(drawable);
            int tintColor = ContextCompat.getColor(application, application.getThemedResourceId(colorAttribute));
            DrawableCompat.setTint(drawable, tintColor);
            return drawable;
          }
        

        如果没有 drawable.wrap,它适用于更高版本,但不适用于 api 级别 16。

        【讨论】:

          【解决方案6】:

          val textInput = EditText(context)
          
          val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
                  drawable?.let { myDrawable ->
                      DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
                      textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
                  }

          【讨论】:

          • 欢迎来到stackoverflow。您能否在答案中添加一些解释?
          【解决方案7】:

          在荣耀 4X 上没有适合我的答案。所以我搜索了更多,发现了这个:

          您只需要通过.invalidateSelf() 要求您的drawable 自行更新

          private void setTint(Drawable drawable, int color) {
              DrawableCompat.setTint(drawable, color);
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
                  drawable.invalidateSelf();
          }
          

          Resourse: Tips for DrawableCompat.setTint() Under API 21

          【讨论】:

          • 我觉得这个条件也没有必要!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-10
          • 1970-01-01
          • 2020-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多