Skip to content

Instantly share code, notes, and snippets.

@qaz10102030
Created September 29, 2021 08:28
Show Gist options
  • Save qaz10102030/4705cf8a3f1ce902f37eaa9675bc3af1 to your computer and use it in GitHub Desktop.
Save qaz10102030/4705cf8a3f1ce902f37eaa9675bc3af1 to your computer and use it in GitHub Desktop.
icon 在 error text 的左邊
// find TextInputLayout
TextInputLayout textInputLayout = findViewById(R.id.textInputLayout);
// set error enable and error text
textInputLayout.setErrorEnabled(true);
textInputLayout.setError(" 需完成信箱驗證唷");
// 關閉原本的錯誤 icon
textInputLayout.setErrorIconDrawable(null);
// 移除 error text 旁邊的 padding
for (int i = 0; i < textInputLayout.getChildCount(); i++) {
textInputLayout.getChildAt(i).setPadding(0, 0, 0, 0);
}
// find error text 的 textview
TextView tv = textInputLayout.findViewById(R.id.textinput_error);
// 計算 textview 的高度
tv.measure(0, 0);
// 拿 Drawable 然後 icon 寬高改成跟 textview 一樣高度
Drawable drawable = getDrawable(R.drawable.ic_err);
drawable.setBounds(0, 0, tv.getMeasuredHeight(), tv.getMeasuredHeight());
// 加 icon 在 textview 左邊
tv.setCompoundDrawables(drawable, null, null, null);
@samuelchou
Copy link

幾乎完美!
不過中間 padding 的部分建議不用執行。執行的話,可能會造成後來新增的 drawable 跑到外側去而被裁切。

@samuelchou
Copy link

samuelchou commented Sep 29, 2021

另外也推薦配合 drawable 染色方法來為 drawable 與 error text 提供一致性:

drawable.setColorFilter(PorterDuffColorFilter(errorCurrentTextColors, PorterDuff.Mode.SRC_IN));

@samuelchou
Copy link

我改寫出 Kotlin 的便捷方法,並且包含上述提及的項目。供他人參考!

/**
 * Calls [TextInputLayout.setError] with additional error drawable setup.
 * Result: drawable will be put in left of error text.
 */
fun TextInputLayout.setErrorWithStartDrawable(errorText: CharSequence?, errorDrawable: Drawable?) {
    error = errorText
    if (errorDrawable == null) return

    val tv: TextView = findViewById(R.id.textinput_error)

    // Make drawable match TextView height.
    tv.measure(0, 0)
    errorDrawable.setBounds(0, 0, tv.measuredHeight, tv.measuredHeight)

    // Make drawable color the same as TextView.
    errorDrawable.colorFilter = PorterDuffColorFilter(errorCurrentTextColors, PorterDuff.Mode.SRC_IN)

    tv.setCompoundDrawables(errorDrawable, null, null, null)
}

/**
 * Calls [TextInputLayout.setError] with additional error drawable setup.
 * Result: drawable will be put in left of error text.
 */
fun TextInputLayout.setErrorWithStartDrawable(
    errorText: CharSequence?, @DrawableRes errorRes: Int?,
) {
    setErrorWithStartDrawable(errorText, errorRes?.let { ContextCompat.getDrawable(context, it) })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment