How to change the size of the EditText hint in TextInputLayout

人盡茶涼 提交于 2019-12-18 09:22:08

问题


I'm trying to change the hint size in TextInputLayout, but it's not working as desired. This is what I'd like to achieve:


styles.xml

<style name="TextLabel" parent="TextAppearance.Design.Hint">
    <item name="android:textSize">44sp</item>
</style>

fragment.xml

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:hintTextAppearance="@style/TextLabel"
    android:hint="Password">

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

</android.support.design.widget.TextInputLayout>

This code works only for the floating label, when the EditText isn't empty, but I want to change the hint size in the EditText itself, when it is empty.


回答1:


The size of the regular hint text is set to the EditText's text size when that is added to the TextInputLayout during inflation/initialization. This value is ultimately set on a private helper class in TextInputLayout, and there is no publicly exposed method or field to change it.

However, we can do a little juggling with the text sizes by subclassing TextInputLayout to intercept the adding of the EditText. When the EditText is added, we cache its text size, set the desired hint size as its text size, allow the super class to add it and initialize the hint, and finally set the EditText's text size back to its original value.

For example:

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

To use the custom mainHintTextSize attribute, we'll need the following in our <resources>, which we can do by just sticking the following file in the res/values/ folder, or adding to the one that's already there.

attrs.xml

<resources>
    <declare-styleable name="CustomTextInputLayout" >
        <attr name="mainHintTextSize" format="dimension" />
    </declare-styleable>
</resources>

If you don't care to use the custom attribute, you can skip this file, and remove the TypedArray processing in the third constructor above.

This custom class is a drop-in replacement for TextInputLayout, and can be used just as it would. For example:

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


This approach is nice, in that it uses only publicly-accessible, documented methods, but the hint text size must be set before the EditText is added, whether that happens during inflation, or through direct instantiation.




回答2:


If you want a hint to have the same size for both expanded and collapsed state. You can write your own custom TextInputLayout

package android.support.design.widget

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.EditText

class ConstantHintSizeTextInputLayout : TextInputLayout {
    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    @SuppressLint("RestrictedApi")
    override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
        super.addView(child, index, params)
        if (child is EditText) {
            collapsingTextHelper.expandedTextSize = collapsingTextHelper.collapsedTextSize
        }
    }
}

Important: Package name should be exactly equal to android.support.design.widget because this solution uses accessing a package-private field, but no reflection involved, so it's fast



来源:https://stackoverflow.com/questions/40184765/how-to-change-the-size-of-the-edittext-hint-in-textinputlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!