Change font of the floating label EditText and TextInputLayout

前端 未结 12 947
北海茫月
北海茫月 2020-12-03 01:23

Someone tried to change the font of the floating label? I changed the source of EditText but the font of the floating label did not change, I am very grateful to those who h

相关标签:
12条回答
  • 2020-12-03 01:37

    In case you too met an exotic requirement to set custom font ONLY to the floating label, and anything else didn't work for you as well, try this. This worked for me, at least for material lib ver. 1.3.0-alpha03.

    @SuppressLint("RestrictedApi")
    fun setHintFontFamily(view: TextInputLayout, fontRes: Int) {
        val font = ResourcesCompat.getFont(view.context, fontRes)!!
    
        try {
            val collapsingTextHelperField =
                view::class.java.getDeclaredField("collapsingTextHelper").apply {
                    isAccessible = true
                }
            val collapsingTextHelper = collapsingTextHelperField.get(view) as CollapsingTextHelper
    
            collapsingTextHelper.collapsedTypeface = font
        } catch (e: Exception) {
        }
    }
    

    First we get the CollapsingTextHelper as in some other answers, but then we use its property collapsedTypeface that seems to do exactly what we need -- apply a font only to the floating label. Please note that this property's visibility is restricted to library group (that's why I used @SuppressLint). So the implementation details might change in the future.

    0 讨论(0)
  • 2020-12-03 01:39

    Use can use style.xml like below:

    Style file:

    <style name="TextInputLayoutErrorStyle" parent="TextAppearance.Design.Error">
        <item name="fontFamily">@font/iran_sans_medium</item>
        <item name="android:fontFamily">@font/iran_sans_medium</item>
    </style>
    
    <style name="TextInputLayoutHintStyle" parent="TextAppearance.Design.Hint">
        <item name="fontFamily">@font/iran_sans_medium</item>
        <item name="android:fontFamily">@font/iran_sans_medium</item>
    </style>
    
    <style name="TextInputLayoutHelperStyle" parent="TextAppearance.Design.HelperText">
        <item name="fontFamily">@font/iran_sans_medium</item>
        <item name="android:fontFamily">@font/iran_sans_medium</item>
    </style>
    
    <style name="TextInputLayoutOutlinedBoxStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
        <item name="helperTextTextAppearance">@style/TextInputLayoutHelperStyle</item>
        <item name="errorTextAppearance">@style/TextInputLayoutErrorStyle</item>
        <item name="hintTextAppearance">@style/TextInputLayoutHintStyle</item>
    </style>
    

    Layout file:

    <com.google.android.material.textfield.TextInputLayout
                android:layout_width="match_parent"
                android:layout_centerInParent="true"
                android:hint="@string/cardname_hint"
                android:layout_marginStart="30dp"
                android:layout_marginEnd="30dp"
                card_view:helperText="@string/cardname_helper"
                style="@style/TextInputLayoutOutlinedBoxStyle"
                android:layout_height="wrap_content">
    
                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:fontFamily="@font/iran_sans_medium"
                    android:textColor="@color/colorTextPrimary"
                    android:layout_height="wrap_content" />
    
    </com.google.android.material.textfield.TextInputLayout>
    
    0 讨论(0)
  • 2020-12-03 01:40

    Unfortunately, you'll have to use reflection to handle this.

    The floating label is drawn by CollapsingTextHelper, which is an internal, package-private class and isn't setup to handle spans. So, using something like a custom TypefaceSpan won't work in this case.

    Because this uses reflection, it isn't guaranteed to work in the future.

    Implementation

    final Typeface tf = Typeface.createFromAsset(getAssets(), "your_custom_font.ttf");
    final TextInputLayout til = (TextInputLayout) findViewById(R.id.yourTextInputLayout);
    til.getEditText().setTypeface(tf);
    try {
        // Retrieve the CollapsingTextHelper Field
        final Field cthf = til.getClass().getDeclaredField("mCollapsingTextHelper");
        cthf.setAccessible(true);
    
        // Retrieve an instance of CollapsingTextHelper and its TextPaint
        final Object cth = cthf.get(til);
        final Field tpf = cth.getClass().getDeclaredField("mTextPaint");
        tpf.setAccessible(true);
    
        // Apply your Typeface to the CollapsingTextHelper TextPaint
        ((TextPaint) tpf.get(cth)).setTypeface(tf);
    } catch (Exception ignored) {
        // Nothing to do
    }
    

    Error view

    If you needed to change the font of the error, you could do one of two things:

    1. Use Reflection grab the error TextView and apply the Typeface much like before
    2. Use a custom span. Unlike the floating label, the error view used by TextInputLayout is just a TextView, so it's able to handle spans.

    Using reflection

    final Field errorField = til.getClass().getDeclaredField("mErrorView");
    errorField.setAccessible(true);
    ((TextView) errorField.get(til)).setTypeface(tf);
    

    Using a custom span

    final SpannableString ss = new SpannableString("Error");
    ss.setSpan(new FontSpan(tf), 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    til.setError(ss);
    
    private static final class FontSpan extends MetricAffectingSpan {
    
        private final Typeface mNewFont;
    
        private FontSpan(Typeface newFont) {
            mNewFont = newFont;
        }
    
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setTypeface(mNewFont);
        }
    
        @Override
        public void updateMeasureState(TextPaint paint) {
            paint.setTypeface(mNewFont);
        }
    
    }
    

    Results

    results

    The font I'm using is Smoothie Shoppe.

    0 讨论(0)
  • 2020-12-03 01:41

    i just found a simple solution and it's worked for me:

    in this way you can set the typeface to hint of any edit text:

    in layout.xml :

     <android.support.design.widget.TextInputLayout
                android:id="@+id/text_input1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <EditText
                    android:id="@+id/edt_user"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/username"/>
            </android.support.design.widget.TextInputLayout>
    

    and in java class :

    public class MainActivity extends AppCompatActivity {
    
    EditText editText;
    TextInputLayout textInputLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Typeface font_yekan= Typeface.createFromAsset(getAssets(), "fonts/byekan.ttf");
            textInputLayout= (TextInputLayout) findViewById(R.id.text_input1);
        textInputLayout.setTypeface(font_yekan);
          }
     }
    
    0 讨论(0)
  • 2020-12-03 01:41

    Here is a custom class implementation for adneal's answer.

    public class CustomTextInputLayout extends TextInputLayout {
    
        public CustomTextInputLayout(Context context) {
            super(context);
            initFont(context);
        }
    
        public CustomTextInputLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            initFont(context);
        }
    
        private void initFont(Context context) {
            final Typeface typeface = Typeface.createFromAsset(
                    context.getAssets(), "fonts/YOUR_CUSTOM_FONT.ttf");
    
            EditText editText = getEditText();
            if (editText != null) {
                editText.setTypeface(typeface);
            }
            try {
                // Retrieve the CollapsingTextHelper Field
                final Field cthf = TextInputLayout.class.getDeclaredField("mCollapsingTextHelper");
                cthf.setAccessible(true);
    
                // Retrieve an instance of CollapsingTextHelper and its TextPaint
                final Object cth = cthf.get(this);
                final Field tpf = cth.getClass().getDeclaredField("mTextPaint");
                tpf.setAccessible(true);
    
                // Apply your Typeface to the CollapsingTextHelper TextPaint
                ((TextPaint) tpf.get(cth)).setTypeface(typeface);
            } catch (Exception ignored) {
                // Nothing to do
            }
        }
    }
    

    In your XML files now you need to use CustomTextInputLayout instead of TextInputLayout and it will work out of the box.

    <your.package.CustomTextInputLayout
        android:id="@+id/textInputLayout_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    
        <AutoCompleteTextView
            android:id="@+id/editText_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress" />
    

    Thanks adneal for the answer.

    0 讨论(0)
  • 2020-12-03 01:44

    There is a simpler way,

    Create a new directory in your 'res' folder named 'font' and put a font in there. Then open your 'styles' file and create a new style :

    <style name="customfontstyle" parent="@android:style/TextAppearance.Small">
            <item name="android:fontFamily">@font/poppins_regular</item>
        </style>
    

    You can add more properties as well, such as textColor, textSize etc..

    Then in your XML:

    <android.support.design.widget.TextInputLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:hintTextAppearance="@style/customfontstyle"
           >
    
            <android.support.design.widget.TextInputEditText
                android:layout_width="220dp"
                android:layout_height="wrap_content"
                android:id="@+id/edit_phone_number"
                android:hint="@string/phone_number_label"
    
                android:inputType="number"
                />
        </android.support.design.widget.TextInputLayout>
    

    I checked it and it works.

    0 讨论(0)
提交回复
热议问题