假设我们有一个简单的EditText,我想将光标(插入符号)更改为其他颜色,在我们使用反射来访问私有字段之前,但是随着Android API Q(29)的引入,我们现在可以使用textCursorDrawable
来设置 Flink 光标的可绘制对象。
下面是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来 Package 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值,并使用color变量更改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)
}
}
}
}
}
2条答案
按热度按时间ldioqlga1#
setTextCursorDrawable()
的文档指出:请注意,应用于光标Drawable的任何更改都将不可见,直到光标被隐藏并再次绘制。
我已经快速浏览了 TextView 和 EditText 代码,还没有确定如何进行您想要的更改。我不是说这件事办不到;我就是看不出来
相反,尝试对您的 WrapDrawable 进行如下更改:
这将起作用,并将保存新 WrapDrawable 的示例化。
更新
不能证明一个否定的,但它看起来像光标drawable不能被替换一旦设置。以下是推理。
对于API 31,在 TextView 代码中只有两个地方设置了光标可绘制。
mCursorDrawable
的私有作用域将限制外部访问。它是绘制光标的文本编辑器类,它返回到 TextView 以获取将要使用的可绘制对象。
loadCursorDrawable
是mDrawableForCursor
唯一被设置的地方,因此一旦定义,就不能更改。由于不能更改,因此不能将其设置为null以拾取可能在文本视图中定义的新光标可绘制对象。因此,总的来说,游标可以在
TextView
中更改,但不能传播到编辑器。anauzrmj2#
您可以使用LayeredDrawable并对其内部Drawable着色:
edit_text_cursor.xml
edit_text_cursor_layer.xml