TextInputLayout
使用一个受限制的库辅助类 CollapsingTextHelper
来操作其提示文本。该辅助类的实例是私有的,与其布局相关的属性都没有暴露出来,因此我们需要使用一些反射技巧来访问它。此外,每次 TextInputLayout
布局时都会设置和重新计算其属性,因此最好继承 TextInputLayout
,重写其 onLayout()
方法,并在那里进行调整。
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import com.google.android.material.textfield.TextInputLayout
class CustomTextInputLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = com.google.android.material.R.attr.textInputStyle
) : TextInputLayout(context, attrs, defStyleAttr) {
private val collapsingTextHelper = try {
TextInputLayout::class.java.getDeclaredField("collapsingTextHelper")
.apply { isAccessible = true }.get(this)
} catch (e: Exception) {
null
}
private val recalculateMethod = collapsingTextHelper?.let { helper ->
try {
helper.javaClass.getDeclaredMethod("recalculate")
} catch (e: Exception) {
null
}
}
private val collapsedBounds = collapsingTextHelper?.let { helper ->
try {
helper.javaClass.getDeclaredField("collapsedBounds")
.apply { isAccessible = true }.get(helper) as Rect
} catch (e: Exception) {
null
}
}
override fun onLayout(
changed: Boolean,
left: Int,
top: Int,
right: Int,
bottom: Int
) {
super.onLayout(changed, left, top, right, bottom)
val edit = editText ?: return
val helper = collapsingTextHelper ?: return
val recalculate = recalculateMethod ?: return
val bounds = collapsedBounds ?: return
bounds.left = edit.left + edit.paddingLeft
try {
recalculate.invoke(helper)
} catch (e: Exception) {
// fail silently
}
}
}
自定义类是常规TextInputLayout
的即插即用替代品。例如:
<com.example.app.CustomTextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Model (Example i10, Swift, etc.)"
app:hintTextAppearance="@style/TextLabel">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/bmw"
android:text="M Series" />
</com.example.app.CustomTextInputLayout>
-keep class android.support.design.widget.TextInputLayout{ *; }
-keep class android.support.design.widget.CollapsingTextHelper{ *; }
- TimTextInputLayout
因其所有新功能而以不同的方式计算边界,因此只使用所示的基本填充计算可能无法正确对齐。 - Mike M.是的,这是我最近遇到的一个常见问题。我用一行简单的代码解决了它:
通过使用 drawble padding
在提示和 drawbleleft
之间放置一个填充。
如果您正在运行时添加 drawble,只需提前在 xml 中添加 drawblepadding
或者您可以动态添加 drawble 填充。
editText.setCompoundDrawablePadding(your padding value);
试一下,然后告诉我。这在我这里有效。