【发布时间】: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