API Q及以上版本的EditText忽略自定义光标可绘制内容

4

我想把自定义的图形设置为EditText的光标。

对于Android Q之前的API,我使用反射并且它可以正常工作。从Android Q开始,我们有了方便的方法setTextCursorDrawable(@Nullable Drawable textCursorDrawable)。我按以下方式使用它:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
   textCursorDrawable = ContextCompat.getDrawable(context,R.drawable.drawable_cursor)!!.tintDrawable(color)
}

tintDrawable 方法的作用是:

private fun Drawable.tintDrawable(@ColorInt color: Int): Drawable {
   return when (this) {
      is VectorDrawableCompat -> this.apply { setTintList(ColorStateList.valueOf(color)) }
      is VectorDrawable -> this.apply { setTintList(ColorStateList.valueOf(color)) }
      else -> {
         val wrappedDrawable = DrawableCompat.wrap(this)
         DrawableCompat.setTint(wrappedDrawable, color)
         DrawableCompat.unwrap(wrappedDrawable)
      }
   }
}

R.drawable.drawable_cursor只是一个简单的矩形形状:

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <size android:width="2dp" />
    <solid android:color="?android:textColorPrimary"  />
</shape>

但是没有任何可见的效果。即使没有应用色彩滤镜,光标的drawable仍然保持不变。

文档中提到:

请注意,对游标Drawable进行的任何更改在隐藏游标然后再次绘制之前都不会可见。

所以我认为我需要手动隐藏光标,并通过 setCursorVisible 方法使其可见,但仍然没有效果。

有人有什么想法吗?我做错了什么吗?

2个回答

4
经过进一步调查,我发现 setTextCursorDrawable(@Nullable Drawable textCursorDrawable) 函数仅适用于 EditText 的每个实例一次。因此,如果您已经将 textCursorDrawable 更改为自定义的对象,则无法再更改为其他对象,它会忽略您想要进行的任何更改。
我的屏幕有默认状态,因此在屏幕初始化期间 setTextCursorDrawable 首次更改了光标的可绘制对象,但是我没有注意到这一点。
因此,请注意这个问题(或者可能是预期行为?):您不能在一个 EditText 实例中多次更改光标的可绘制对象。

0
如上所述,Oleksii Yerastov提到textCursorDrawable只能设置一次。这意味着您无法更改可绘制对象。但是更改颜色并不是问题。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    val cursor = binding.textInputEditText.textCursorDrawable
    cursor?.let {
        when (it) {
            is ShapeDrawable -> it.paint.color = textCursorColor
            is GradientDrawable -> it.setColor(textCursorColor)
            is ColorDrawable -> it.color = textCursorColor
        }
    } ?: run {
        binding.textInputEditText.setTextCursorDrawable(textCursorDrawable)
    }
} else {
    val field = TextView::class.java.getDeclaredField("mCursorDrawableRes")
    field.isAccessible = true
    field.set(binding.textInputEditText, textCursorDrawable)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接