如何在TextInputLayout上显示成功状态(类似setError())

问题描述 投票:0回答:1

我需要在 Material 的

TextInputLayout
上显示成功状态。我只需要与设置错误时显示的布局相同的 UI。以下是我需要的:

class CustomTextInputLayout(
    context: Context,
    attributes: AttributeSet?,
): TextInputLayout(context, attributes) {
    fun setSuccessMode(successText: CharSequence?)
    fun setErrorMode(errorText: CharSequence?)
    fun setHelperTextMode(helperText: CharSequence?)
}

我不知道如何使用主题和样式来做到这一点。我计划欺骗

TextInputLayout
根据变量显示不同的颜色,但仍然使用
setError()
功能。但是,我认为我无法在运行时轻松更改
TextInputLayout
的主题。另外,引入变量需要我在
savedState
更改中保留它。

android android-textinputlayout
1个回答
0
投票

这就是我最终使用的:

/**
 * Utility class for managing different states (success, error, helper) of a [TextInputLayout].
 *
 *
 * This utility class allows you to easily switch between success, error, and idle states of a
 * TextInputLayout by providing appropriate colors and text for each state.
 *
 * @param textInputLayout The TextInputLayout to be managed by this utility class.
 * @param successColorAttr The theme attribute for the color in success mode.
 *        Default value is [com.google.android.material.R.attr.colorTertiary].
 * @param errorColorAttr The theme attribute for the color in error mode.
 *        Default value is [com.google.android.material.R.attr.colorError].
 * @param idleColorAttr The theme attribute for the color in idle mode.
 *        Default value is [com.google.android.material.R.attr.colorPrimary].
 */
class TextInputLayoutUtil(
    private val textInputLayout: TextInputLayout,
    @AttrRes private val successColorAttr: Int = com.google.android.material.R.attr.colorTertiary,
    @AttrRes private val errorColorAttr: Int = com.google.android.material.R.attr.colorError,
    @AttrRes private val idleColorAttr: Int = com.google.android.material.R.attr.colorPrimary,
) {

    /**
     * Gets the context of the [TextInputLayout].
     */
    private val context: Context
        get() = textInputLayout.context

    /**
     * Sets the [TextInputLayout] to success mode with the specified success text.
     *
     * @param successText The text to be displayed in the success mode.
     */
    fun setSuccessMode(successText: CharSequence?) {
        textInputLayout.setError(successText)
        textInputLayout.setErrorIconDrawable(R.drawable.ic_success)

        val successColorStateList = getColorStateListFromAttr(successColorAttr)
        textInputLayout.setErrorTextColor(successColorStateList)
        textInputLayout.setHintTextColor(successColorStateList)
        textInputLayout.setErrorIconTintList(successColorStateList)
        textInputLayout.setBoxStrokeErrorColor(successColorStateList)
    }

    /**
     * Sets the [TextInputLayout] to error mode with the specified error text.
     *
     * @param errorText The text to be displayed in the error mode.
     */
    fun setErrorMode(errorText: CharSequence?) {
        textInputLayout.setError(errorText)
        textInputLayout.setErrorIconDrawable(R.drawable.ic_error)

        val errorColorStateList = getColorStateListFromAttr(errorColorAttr)
        textInputLayout.setErrorTextColor(errorColorStateList)
        textInputLayout.setHintTextColor(errorColorStateList)
        textInputLayout.setErrorIconTintList(errorColorStateList)
        textInputLayout.setBoxStrokeErrorColor(errorColorStateList)
    }

    /**
     * Sets the [TextInputLayout] to helper text mode with the specified helper text.
     *
     * @param helperText The text to be displayed in the helper text mode.
     */
    fun setHelperTextMode(helperText: CharSequence?) {
        textInputLayout.setError(null)

        val hintColorStateList = getColorStateListFromAttr(idleColorAttr)
        textInputLayout.setHintTextColor(hintColorStateList)
        textInputLayout.setHelperText(helperText)
    }

    /**
     * Retrieves a [ColorStateList] based on the specified theme attribute.
     *
     * @param attr The theme attribute to retrieve the color for.
     * @return A [ColorStateList] based on the specified theme attribute.
     */
    private fun getColorStateListFromAttr(
        @AttrRes attr: Int
    ): ColorStateList? {
        val colorResId = context.resolveColorResIdFromAttribute(attr)
        return ContextCompat.getColorStateList(context, colorResId)
    }
}

fun Context.resolveColorResIdFromAttribute(@AttrRes attrId: Int): Int {
    var typedArray: TypedArray? = null
    return try {
        typedArray = obtainStyledAttributes(intArrayOf(attrId))
        typedArray.getResourceId(0, 0)
    } finally {
        typedArray?.recycle()
    }
}

我不确定这是否是最好的方法。而且,我仍然觉得我应该使用主题/样式/选择器来做到这一点,但我不知道类似的事情是否可能。

我最终不想扩展

TextInputLayout
,因为这个实现可以在没有自定义类的情况下工作。这也使我免于管理视图的状态。

这就是现在的样子(材料3):

错误

成功

空闲/帮助文本

© www.soinside.com 2019 - 2024. All rights reserved.