我认为PhúcNguyễn的想法很好,将
TextView和
EditText结合起来以实现您要寻找的内容。您可以将它们作为单独的字段放置在布局中,或者将它们放置在组合视图中。无论哪种方式,效果都是相同的,您都可以实现所需的内容。
您已经知道如何处理字段开头的静态文本。下面我将介绍如何处理下划线,以便输入的字符看起来像是覆盖了下划线。
对于演示,我将一个带有静态文本的
TextView与自定义的
EditText放在一起。真正有趣的是自定义的
EditText。通过自定义视图,覆盖了
onDraw()函数以将下划线写成背景的一部分。尽管这些下划线看起来像字段中的任何其他字符,但除了用户输入时逐个覆盖下划线外,它们不能被选中、删除、跳过或以任何方式操作。自定义视图的末尾填充被操纵以提供下划线和文本的空间。
![enter image description here](https://istack.dev59.com/2X35z.gif)
这是自定义视图:
EditTextFillInBlanks.kt
class EditTextFillInBlanks @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : androidx.appcompat.widget.AppCompatEditText(context, attrs, defStyleAttr) {
private var mBaseRightPadding = 0
private var mTextWidth = 0f
private var mMaxLength = 0
private lateinit var mBlanks: String
private val mUnspecifiedWidthHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
init {
mBaseRightPadding = paddingRight
doOnTextChanged { text, _, _, _ ->
measure(mUnspecifiedWidthHeight, mUnspecifiedWidthHeight)
mTextWidth = measuredWidth.toFloat() - paddingStart - paddingEnd
updatePaddingForBlanks(text)
}
setText("", BufferType.EDITABLE)
}
private fun updatePaddingForBlanks(text: CharSequence?) {
if (mMaxLength <= 0) {
mMaxLength = determineMaxLen()
check(mMaxLength > 0) { "Maximum length must be > 0" }
}
text?.apply {
val blanksCount = max(0, mMaxLength - length)
mBlanks = "_".repeat(blanksCount).apply {
updatePadding(right = mBaseRightPadding + paint.measureText(this).toInt())
}
}
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (mBlanks.isNotEmpty()) {
canvas?.withSave {
drawText(mBlanks, paddingStart + mTextWidth, baseline.toFloat(), paint)
}
}
}
fun setMaxLen(maxLen: Int) {
mMaxLength = maxLen
}
private fun determineMaxLen(): Int {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return 0
return filters.firstOrNull { it is InputFilter.LengthFilter }
?.let {
it as InputFilter.LengthFilter
it.max
} ?: 0
}
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:text="+12345"
android:textColor="@android:color/black"
android:textSize="36sp"
app:layout_constraintBaseline_toBaselineOf="@id/editableSuffix"
app:layout_constraintEnd_toStartOf="@+id/editableSuffix"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/guideline2" />
<com.example.edittextwithblanks.EditTextFillInBlanks
android:id="@+id/editableSuffix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/edittext_background"
android:inputType="number"
android:maxLength="@integer/blankFillLen"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:textColor="@android:color/black"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="parent"
tools:text="____">
<requestFocus />
</com.example.edittextwithblanks.EditTextFillInBlanks>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="92dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val mStaticStart = "+12345"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (BuildConfig.VERSION_CODE < Build.VERSION_CODES.P) {
val maxLen = resources.getInteger(R.integer.blankFillLen)
findViewById<EditTextFillInBlanks>(R.id.editableSuffix).setMaxLen(maxLen)
}
}
}
很可能你可以将静态文本处理并入自定义视图中,以获得完整的解决方案。
afterTextChange(Editable editable)
,您可以使用可编辑的内容来更新下划线。我认为当您插入字符时,可以调用该方法来删除下划线。尝试阅读此SO以获取更多想法。 - Dennis Nguyen+12345____
,而maxLength
是10时,afterTextChanged
不会被调用。 - Sergei Mikhailovskii