【问题标题】:How to set the color of the cursor(caret) multiple times in Android如何在Android中多次设置光标(插入符号)的颜色
【发布时间】:2022-09-27 20:10:49
【问题描述】:

假设我们有一个简单的 EditText,我想将光标(插入符号)更改为其他颜色,在我们使用反射来访问私有字段之前,但是随着 Android API Q(29) 的引入,我们现在可以使用textCursorDrawable 设置闪烁光标的可绘制对象。

这是 EditText 的 xml 代码

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    xmlns:app=\"http://schemas.android.com/apk/res-auto\"
    xmlns:tools=\"http://schemas.android.com/tools\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    tools:context=\".MainActivity\">

    <EditText
        android:id=\"@+id/editText\"
        android:layout_width=\"match_parent\"
        android:layout_height=\"wrap_content\"
        android:text=\"Test\"
        android:textSize=\"30sp\"
        app:layout_constraintStart_toStartOf=\"parent\"
        app:layout_constraintTop_toTopOf=\"parent\" />

</androidx.constraintlayout.widget.ConstraintLayout>

现在我们可以使用 WrapDrawable 来包装 ColorDrawable,它将设置为 EditText 的textCursorDrawable 值,以便我们更改光标颜色。

以下是 WrapDrawable 的代码:

class WrapDrawable(color: Int) : Drawable() {

    private var drawable = ColorDrawable(color)

    @ColorInt
    var color: Int = color
        set(value) {
            field = value
            drawable = ColorDrawable(value)
        }

    override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
        super.setBounds(left, top, right, bottom)
        drawable.setBounds(left, top, right, bottom)
    }

    override fun getConstantState(): ConstantState? {
        return drawable.constantState
    }

    override fun setAlpha(alpha: Int) {
        drawable.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        drawable.colorFilter = colorFilter
    }

    override fun getOpacity(): Int {
        return drawable.alpha
    }

    override fun draw(canvas: Canvas) {
        drawable.draw(canvas)
    }

    override fun getIntrinsicWidth(): Int {
        return drawable.bounds.width()
    }

    override fun getIntrinsicHeight(): Int {
        return drawable.bounds.height()
    }
}

在下面的代码中,我们将光标的颜色两次更改为Color.RED,第二次更改为Color.BLUE,现在我们应该期望有一个蓝色光标。 但问题是,一旦textCursorDrawable已设置,即使我们尝试取消它,我们也无法更改它。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = findViewById<EditText>(R.id.editText)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            // set the cursor color to RED
            text.textCursorDrawable = WrapDrawable(Color.RED).apply {
                setBounds(0, 0, 5, text.lineHeight)
            }
            
            // set the cursor color to BLUE !!! NOT WORKING !!!
            text.textCursorDrawable = WrapDrawable(Color.BLUE).apply {
                setBounds(0, 0, 5, text.lineHeight)
            }
        }
    }
}

所以我的问题是我们如何多次重新分配textCursorDrawable 值?

我通过更新已经存在的 textCursorDrawable 值并使用颜色变量更改 ColorDrawable 找到了一种解决方法。


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = findViewById<EditText>(R.id.editText)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            // set the cursor color to RED
            text.textCursorDrawable = WrapDrawable(Color.RED).apply {
                setBounds(0, 0, 5, text.lineHeight)
            }

            // set the cursor color to BLUE
            text.textCursorDrawable?.let {
                if (it is WrapDrawable) {
                    it.color = Color.BLUE
                    it.setBounds(0, 0, 5, text.lineHeight)
                }
            }
        }
    }
}

    标签: android android-edittext android-cursor


    【解决方案1】:

    setTextCursorDrawable() 的文档指出:

    请注意,应用于光标 Drawable 的任何更改将不可见,直到光标被隐藏然后再次绘制。

    我快速浏览了一下文本视图编辑文本代码并且尚未确定如何进行所需的更改。我并不是说它不能做到。我只是没看到。

    相反,请尝试更改您的WrapDrawale像这样:

    (text.textCursorDrawable as WrapDrawable).apply {
        color = Color.BLUE
        setBounds(0, 0, 5, text.lineHeight)
    }
    

    这将起作用并将保存新的实例化WrapDrawable.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      • 2010-10-20
      • 2015-09-07
      相关资源
      最近更新 更多