是否可以为InputTextLayout的浮动文本和提示文本使用不同的字体

时间:2016-10-23 08:33:26

标签: android android-fonts

目前,我希望对InputTextLayout的浮动文字产生大胆的影响。这就是我正在做的事情

this.usernameTextInputLayout.setTypeface(Utils.ROBOTO_BOLD_TYPE_FACE);

它按预期工作。浮动文本(用户名)变为粗体。

enter image description here

但是,这会给我带来另一种不良影响。提示文本也会变为粗体。

enter image description here

您可以比较以上2张图片。请注意,为了进行比较,我只是保留passwordTextInputLayout

对于InputTextLayout的浮动文本和提示文本,是否可以使用不同的字体?

1 个答案:

答案 0 :(得分:4)

如您所知,TextInputLayout使用私有帮助程序类来处理提示文本样式和动画。此类 - CollapsingTextHelper - 为其折叠展开状态维护单独的字体。我们只需要设置正确的,我们将使用反射。

我通常将这些功能打包到自定义子类中,所以我会在这里做同样的事情。如果您不想使用子类,可以将反射内容轻松地转换为可以放在Activity或实用程序类中的一些简单方法。

public class CustomTextInputLayout extends TextInputLayout {

    private Object collapsingTextHelper;
    private Method setCollapsedTypefaceMethod;
    private Method setExpandedTypefaceMethod;

    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);

        init();
    }

    private void init() {
        try {
            Field cthField = TextInputLayout.class
                .getDeclaredField("mCollapsingTextHelper");
            cthField.setAccessible(true);
            collapsingTextHelper = cthField.get(this);

            setCollapsedTypefaceMethod = collapsingTextHelper
                .getClass().getDeclaredMethod("setCollapsedTypeface", Typeface.class);
            setCollapsedTypefaceMethod.setAccessible(true);

            setExpandedTypefaceMethod = collapsingTextHelper
                .getClass().getDeclaredMethod("setExpandedTypeface", Typeface.class);
            setExpandedTypefaceMethod.setAccessible(true);
        }
        catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
            collapsingTextHelper = null;
            setCollapsedTypefaceMethod = null;
            setExpandedTypefaceMethod = null;
            e.printStackTrace();
        }
    }

    public void setCollapsedTypeface(Typeface typeface) {
        if (collapsingTextHelper == null) {
            return;
        }

        try {
            setCollapsedTypefaceMethod.invoke(collapsingTextHelper, typeface);
        }
        catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void setExpandedTypeface(Typeface typeface) {
        if (collapsingTextHelper == null) {
            return;
        }

        try {
            setExpandedTypefaceMethod.invoke(collapsingTextHelper, typeface);
        }
        catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

有些违反直觉,TextInputLayout 崩溃状态是指提示是EditText上方的浮动标签。它的扩展状态是指提示位于EditText内的“正常”位置。上面给出了为两种状态设置字体的方法。

这是TextInputLayout的替代品,您可以在布局中使用它,就像您一样。例如:

<com.mycompany.myapp.CustomTextInputLayout
    android:id="@+id/username_til"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:hintTextAppearance="@style/TextLabel">

    <android.support.design.widget.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:hint="Username" />

</com.mycompany.myapp.CustomTextInputLayout>

在您的代码中,设置浮动文本提示的字体:

CustomTextInputLayout usernameTextInputLayout =
    (CustomTextInputLayout) findViewById(R.id.username_til);

usernameTextInputLayout.setCollapsedTypeface(Utils.ROBOTO_BOLD_TYPE_FACE);

上面使用的CollapsingTextHelper方法已添加到支持库的23.1.0版中。如果您使用的是以前的版本,或者由于其他原因而获得了NoSuchMethodException,那么无论版本如何,直接设置字体字段的the original version of my answer都应该有效。