我需要在 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
更改中保留它。
这就是我最终使用的:
/**
* 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):