Change font of the floating label EditText and TextInputLayout
As of Design Library v23
, you can use TextInputLayout#setTypeface()
.
This will set the typeface on both the expanded and floating hint.
Here is the feature request where it was discussed on b.android.com.
EDIT: The error view typeface was not being set, but is now fixed in v25.1.0
.
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:
- Use Reflection grab the error
TextView
and apply theTypeface
much like before - Use a custom span. Unlike the floating label, the error view used by
TextInputLayout
is just aTextView
, 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
The font I'm using is Smoothie Shoppe.
I'm using new MaterialComponents
theme and none of the answers helped me.
Had to play with styles and themes on my own. Will post a chunk of styles here in case somebody faces the same issue.
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> ... <item name="textInputStyle">@style/CustomFontTextInputLayout</item></style> <!-- region TextInputLayout & TextInputEditText styles --><style name="TextInputLayout.OutlineBox.CustomFont" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox"> <item name="android:theme">@style/ThemeOverlay.TextInputEditText.OutlinedBox.CustomFont</item></style><style name="ThemeOverlay.TextInputEditText.OutlinedBox.CustomFont" parent="ThemeOverlay.MaterialComponents.TextInputEditText.OutlinedBox"> <item name="editTextStyle">@style/TextInputEditText.OutlinedBox.CustomFont</item></style><style name="TextInputEditText.OutlinedBox.CustomFont" parent="Widget.MaterialComponents.TextInputEditText.OutlinedBox"> <item name="android:fontFamily">@font/my_font</item></style><style name="CustomFontTextInputLayout" parent="Widget.Design.TextInputLayout"> <item name="hintTextAppearance">@style/TextInputLayoutHintText</item> <item name="helperTextTextAppearance">@style/TextInputLayoutHelperText</item> <item name="errorTextAppearance">@style/TextInputLayoutErrorText</item></style><style name="TextInputLayoutHintText" parent="TextAppearance.Design.Hint"> <item name="android:fontFamily">@font/my_font</item></style><style name="TextInputLayoutHelperText" parent="TextAppearance.Design.HelperText"> <item name="android:fontFamily">@font/my_font</item></style><style name="TextInputLayoutErrorText" parent="TextAppearance.Design.Error"> <item name="android:fontFamily">@font/my_font</item></style><!-- endregion -->
Then in xml layout:
<android.support.design.widget.TextInputLayout style="@style/TextInputLayout.OutlineBox.CustomFont" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/first_name"/></android.support.design.widget.TextInputLayout>
Here's the result: