【问题标题】:DrawableCompat tinting does not work on pre-LollipopDrawableCompat 着色在棒棒糖之前不起作用
【发布时间】:2015-09-01 12:55:23
【问题描述】:

我正在使用新的 TextInputLayout 来包装 EditText。当我确定一个字段有错误时,我会执行以下操作:

Drawable drawable = DrawableCompat.wrap(getEditText().getBackground());

DrawableCompat.setTintList(drawable, ColorStateList.valueOf(Color.RED));

这适用于 5.0 并将下划线变为红色,但在 4.4 或 4.1 测试设备上不起作用。我在这里想念什么?看起来很简单,根据谷歌“只是工作”......很确定我也有它的最新版本:

编译'com.android.support:design:22.2.0'

FWIW,如果我使用 setColorFilter 而不是 setTint,那么它可以在所有平台上运行,但是我会遇到问题,它会在焦点设置/离开/等后立即消失并且不会回来......我更喜欢用色调来做(如果有人正在寻找额外的信用,真的更喜欢让色调应用于焦点和非焦点状态)

谢谢!

【问题讨论】:

  • 通常那些 Compat 类什么都不做。他们查看 API 级别,是否支持相关功能,然后他们会这样做,如果不是,他们就什么也不做。只需自己查看源代码并找出答案。我会自己看一下,但我现在正在打电话。
  • 换句话说就是你正在经历的行为。 Compat 类唯一真正的特点是您可以使用它们而不必担心兼容性。如果某些东西不受支持,那么发生的一切都不算什么。这当然不能说是真的。
  • 这不是这里所声称的。 DrawableCompat 专门用于将着色带入 API 级别 4 及更高版本。 chris.banes.me/2015/04/22/support-libraries-v22-1-0
  • 是的,我只是查看了源代码,有针对不同 API 级别的实现。实际上,通过查看源代码,我发现了:对wrap() 的调用将Drawable 包装成一个新的DrawableWrapper。这个DrawableWrapper 用于在旧设备上实现着色。这样做的结果——因为DrawableWrapper 是一个新的Drawable——你必须在之后再次将wrap() 返回的Drawable 设置回EditText。因此,只需致电editText.setBackground(drawable) 即可。
  • 默认背景可能有单独的焦点状态集。尝试使用自定义 Drawable 作为背景。

标签: android drawable tint


【解决方案1】:

当您调用wrap() 时,原来的Drawable 会在内部包装成一个新的DrawableWrapper,用于在旧设备上实现着色。因此,要使其正常工作,您必须将返回的 Drawable 设置回 EditText

final Drawable originalDrawable = editText.getBackground();
final Drawable wrappedDrawable = DrawableCompat.wrap(originalDrawable);
DrawableCompat.setTintList(wrappedDrawable, ColorStateList.valueOf(Color.RED));
editText.setBackground(wrappedDrawable);

从支持库的 23.2.0 版本开始,您还可以使用 setTint() 而不是 setTintList() 来设置一种色调颜色,而无需创建 ColorStateList

DrawableCompat.setTint(wrappedDrawable, Color.RED);

如果您想确保 API 级别 16 之后的向后兼容性,您会遇到一些障碍。 setBackground() 是在 API 级别 16 中添加的,您需要在此之前在设备上调用 setBackgroundDrawable()。最好实现一个帮助方法来为你做这件事:

public static void setBackground(View view, Drawable background) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        view.setBackground(background);
    } else {
        view.setBackgroundDrawable(background);
    }
}

【讨论】:

  • @toobsco42 这根本不是真的。我不明白你认为什么不适用于 Lollipop 或更低版本。此答案中的代码适用于 API 级别 4 一直到 23。
  • 这是我尝试过的 gist.github.com/lawloretienne/5703098d2d32ee92082a 并且仅在 API 级别 21 上没有正确着色。
  • 似乎有一个可能与此相关的失效错误,请参阅:code.google.com/p/android/issues/detail?id=172067#c13
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 2015-09-10
  • 2015-05-07
  • 2017-06-24
  • 1970-01-01
  • 2018-12-07
  • 1970-01-01
  • 2015-12-24
相关资源
最近更新 更多