Agregue un prefijo a TextInputEditText | de Rohail Ahmad | Octubre de 2020

Prefijo de moneda

Añadiendo un prefijo en TextInputEditText cual es siempre visible es sorprendentemente difícil TextInputLayout. Hay mucho código para manejar esto en TextWatcher. ¡Pero hay una manera más fácil!

Usar TextWatcher para agregar un prefijo siempre visible es bastante complicado, si alguien hace clic en el medio de su prefijo, debe capturar el texto y moverlo al final o más del cursor al final inmediatamente. Todo esto puede resultar en MUCHOS códigos. Debe deshabilitar copiar / pegar, debe poder manejar onClick, debe poder cambiar el texto, etc.

Seleccionar todo el texto

Es difícil igualar el backgroand text y EditText. La razón es que el relleno está en DIP y los tamaños de texto están en SP. Mirar problemas de compatibilidad aquí para obtener más información sobre la fragmentación de EditText. La ampliación sería un enfoque más sencillo TextInputEditText lo que significa crear el tuyo propio PrefijoEditarTexto.

Admite cambiar el texto del prefijo. Tampoco revisé la pantalla de derecha a izquierda, pero debería ser lo suficientemente simple.

Utilizo tempPrefix porque si establece un prefijo antes de que se enfoque, el prefijo estará visible en todo momento. Mediante el uso onFocusChanged los oyentes pueden establecer un prefijo y luego será visible al enfocarse en esta vista.

class PrefixEditText(context: Context, attributes: AttributeSet?) :
TextInputEditText(context, attributes) {

private var mOriginalLeftPadding: Float = -1f
private var prefix = ""
private var tempPrefix = ""

init {
context.obtainStyledAttributes(attributes, R.styleable.PrefixEditText).apply {
getString(R.styleable.PrefixEditText_prefix)?.let { setPrefixes(it) }
}
.recycle()
}

fun setPrefixes(fix: String) {
tempPrefix = fix
}

override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
super.onFocusChanged(focused, direction, previouslyFocusedRect)
if (focused)
prefix = tempPrefix

}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
calculatePrefix()
}

private fun calculatePrefix() {
if (mOriginalLeftPadding == -1f && prefix.isNotEmpty()) {
val widths = FloatArray(prefix.length)
paint.getTextWidths(prefix, widths)
var textWidth = 0f
for (w in widths) {
textWidth += w
}
mOriginalLeftPadding = compoundPaddingLeft.toFloat()
setPadding(
(textWidth + mOriginalLeftPadding).toInt(),
paddingRight, paddingTop,
paddingBottom
)
}
}

override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (prefix.isNotEmpty())
canvas?.drawText(
prefix, mOriginalLeftPadding,
getLineBounds(0, null).toFloat(), paint
)
}
}

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/amountLayout"
style="@style/EliqInputLayoutStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_standard"
android:hint="Amount"
android:minWidth="@dimen/buttonWidthNormal">

<io.eliq.core.ui_components.PrefixEditText
android:id="@+id/etAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:selectAllOnFocus="true" />
</com.google.android.material.textfield.TextInputLayout>

<resources><declare-styleable name="PrefixEditText">
<attr name="prefix" format="string" />
</declare-styleable>
</resources>
etAmount.setPrefixes(viewModel.getCurrencySymbol())

En este caso, estoy usando una instancia de moneda de NumberFormat.

fun getCurrencySymbol(): String = NumberFormat.getCurrencyInstance().currency?.symbol ?: ""

¡Yayyy! Eso es todo. Creo que podrá sintonizarse con sus necesidades.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *