常规提示文本的大小设置为EditText 在膨胀/初始化期间添加到TextInputLayout 的文本大小。此值最终设置在 TextInputLayout 中的私有帮助程序类上,并且没有公开暴露的方法或字段来更改它。
但是,我们可以通过子类化TextInputLayout 来拦截EditText 的添加,从而对文本大小进行一些调整。当EditText被添加时,我们缓存它的文本大小,将所需的提示大小设置为它的文本大小,允许超类添加它并初始化提示,最后将EditText的文本大小设置回它的原值。
例如:
public class CustomTextInputLayout extends TextInputLayout {
private float mainHintTextSize;
private float editTextSize;
public CustomTextInputLayout(Context context) {
this(context, null);
}
public CustomTextInputLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.CustomTextInputLayout);
mainHintTextSize = a.getDimensionPixelSize(
R.styleable.CustomTextInputLayout_mainHintTextSize, 0);
a.recycle();
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
final boolean b = child instanceof EditText && mainHintTextSize > 0;
if (b) {
final EditText e = (EditText) child;
editTextSize = e.getTextSize();
e.setTextSize(TypedValue.COMPLEX_UNIT_PX, mainHintTextSize);
}
super.addView(child, index, params);
if (b) {
getEditText().setTextSize(TypedValue.COMPLEX_UNIT_PX, editTextSize);
}
}
// Units are pixels.
public float getMainHintTextSize() {
return mainHintTextSize;
}
// This optional method allows for dynamic instantiation of this class and
// its EditText, but it cannot be used after the EditText has been added.
// Units are scaled pixels.
public void setMainHintTextSize(float size) {
if (getEditText() != null) {
throw new IllegalStateException(
"Hint text size must be set before EditText is added");
}
mainHintTextSize = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, size, getResources().getDisplayMetrics());
}
}
要使用自定义mainHintTextSize 属性,我们需要在<resources> 中添加以下文件,只需将以下文件粘贴到res/values/ 文件夹中,或添加到已经存在的文件中即可。
attrs.xml
<resources>
<declare-styleable name="CustomTextInputLayout" >
<attr name="mainHintTextSize" format="dimension" />
</declare-styleable>
</resources>
如果你不介意使用自定义属性,可以跳过这个文件,去掉上面第三个构造函数中的TypedArray处理。
这个自定义类是TextInputLayout 的直接替代品,可以照原样使用。例如:
<com.mycompany.myapp.CustomTextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
app:hintTextAppearance="@style/TextLabel"
app:mainHintTextSize="12sp">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="qwerty123" />
</com.mycompany.myapp.CustomTextInputLayout>
这种方法很好,因为它仅使用可公开访问的记录方法,但提示文本大小必须在添加 EditText 之前设置,无论是在膨胀期间发生还是通过直接实例化发生。