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
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.
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>
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:
TextView
and apply the Typeface
much like beforeTextInputLayout
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
The font I'm using is Smoothie Shoppe.
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);
}
}
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.
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.