Change font of the floating label EditText and TextInputLayout - android

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 help me
Code:
<android.support.design.widget.TextInputLayout
android:id="#+id/tilTextoDescricao"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/tilValorUnidade"
android:layout_marginTop="10dp">
<EditText
android:id="#+id/etTextoDescricao"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:hint="Descrição"
android:textSize="15dp"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
-----------------
etTextoDescricao= (EditText) findViewById(R.id.etTextoDescricao);
etTextoDescricao.setTypeface(CustomTypeface.getTypefaceMediumDefault(this));

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 the Typeface much like before
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
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:

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.

final Typeface tf = Typeface.createFromAsset(getAssets(), "your_custom_font.ttf");
final TextInputLayout til = (TextInputLayout) findViewById(R.id.yourTextInputLayout);
til.getEditText().setTypeface(tf);
til.setTypeface(tf);

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.

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>

I was looking for this, I found this way, using the support library:
Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
and set this typeface to yout TextInpuLayout.
For me works like charm, I hope it helps others =]
Source: Documentation

fixing a problem in #adneal answer:
if setErrorEnabled is not set true, mErrorView would be null and if you set it false at any point the font would change back to default.
so to fix it:
in you custom TextInputLayout override setErrorEnabled
#Override
public void setErrorEnabled(boolean enabled) {
super.setErrorEnabled(enabled);
if (enabled) {
try {
Field cthf = TextInputLayout.class.getDeclaredField("mErrorView");
cthf.setAccessible(true);
TextView error = (TextView) cthf.get(this);
if (error != null)
error.setTypeface(tf);
} catch (Exception e) {
}
}
}

This is how i achieve this
edit_login_emailOrPhone.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
{
textInputLayout_login_emailOrPhone.setTypeface(APSApplication.getInstance().getFonts().getTypefaceSemiBold());
}else
{
textInputLayout_login_emailOrPhone.setTypeface(APSApplication.getInstance().getFonts().getTypefaceRegular());
}
}
});

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.

Related

How can change Textsize of activity_main_drawer in Navigation drawer activity [duplicate]

Google recently released the android.support.design.widget.NavigationView widget as part of the com.android.support:design:22.2.0 library, which greatly simplified (and standardises) the process of creating a NavigationDrawer.
However according to the design specs, the list item should be Roboto Medium, 14sp, 87% #000000. The NavigationView exposes no textSize or textStyle to customise this.
What are my options if I'm pedantic about maintaining the correct design specifications using the Google provided NavigationView (or customising it in any other way)?
Create new style at the file app/src/main/res/values/styles.xml
<style name="NavigationDrawerStyle">
<item name="android:textSize">20sp</item><!-- text size in menu-->
<!-- item size in menu-->
<item name="android:listPreferredItemHeightSmall">40dp</item>
<item name="listPreferredItemHeightSmall">40dp</item>
<!-- item padding left in menu-->
<item name="android:listPreferredItemPaddingLeft">8dp</item>
<item name="listPreferredItemPaddingLeft">8dp</item>
<!-- item padding right in menu-->
<item name="android:listPreferredItemPaddingRight">8dp</item>
<item name="listPreferredItemPaddingRight">8dp</item>
</style>
Add it to your main_layout.xml
<android.support.design.widget.NavigationView
...
app:theme="#style/NavigationDrawerStyle"
....>
</android.support.design.widget.NavigationView>
All params of the navigation items (which you can change) are located here (path to file ...\sdk\extras\android\support\design\res\layout\design_navigation_item.xml )
design_navigation_item.xml
<android.support.design.internal.NavigationMenuItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="#dimen/navigation_icon_padding"
android:gravity="center_vertical|start"
android:maxLines="1"
android:fontFamily="sans-serif-thin"
android:textSize="22sp"
android:textAppearance="?attr/textAppearanceListItem" />
Also you can override *.xml file (copy file from ...\sdk\extras\android\support\design\res\layout\design_navigation_item.xml), just in your app/src/main/res/layout folder create a layout named the same design_navigation_item.xml.
All layouts which can be Overriden are located here ...\sdk\extras\android\support\design\res\layout\
design_layout_snackbar.xml
design_layout_snackbar_include.xml
design_layout_tab_icon.xml
design_layout_tab_text.xml
design_navigation_item.xml
design_navigation_item_header.xml
design_navigation_item_separator.xml
design_navigation_item_subheader.xml
design_navigation_menu.xml
[UPDATE] Each version of com.android.support:design-{version} lib has different items to override.
Check all what you need in
[UPDATE 04/14/2020]
If you are using com.google.android.material.navigation.NavigationView
then open the class, and you will see:
public NavigationView(#NonNull Context context, #Nullable AttributeSet attrs) {
this(context, attrs, R.attr.navigationViewStyle);
}
So you can use attr navigationViewStyle to set your own style for the NavigationView via theme of your app:
NB: parent theme of AppTheme should be Theme.MaterialComponents
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
...
<item name="navigationViewStyle">#style/AppNavigationViewStyle</item>
...
</style>
<style name="AppNavigationViewStyle" parent="Widget.MaterialComponents.NavigationView">
<item name="itemTextAppearance">#style/AppNavigationViewItemTextAppearance</item>
</style>
<style name="AppNavigationViewItemTextAppearance" parent="#style/TextAppearance.MaterialComponents.Subtitle2">
<item name="android:textSize">18sp</item>
</style>
Just open parent theme to see all <item name attrs for override
Since Android Support Library 22.2.1, Google has changed default textSize of items in NavigationView from 16sp to 14sp, which suits Material Design guideline well. However, in some cases(for example, when you want to support Chinese language), it seems larger textSize is better. Solution is simple:
add app:theme="#style/yourStyle.Drawer" to your NavigationView in your layout.xml
in styles.xml, add android:textSize="16sp" in style yourStyle.Drawer
You can customize everything from text color to size and font in your style.xml
<style name="NavDrawerTextStyle" parent="Base.TextAppearance.AppCompat">
<item name="android:textColor">#color/colorPrimaryDark</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
</style>
and then in your NavigationView:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.NavigationView
...
android:itemTextAppearance="#style/NavDrawerTextStyle"
/>
you can use this attributes inside xml file
app:itemTextAppearance="?android:attr/textAppearanceMedium"
or for small text
app:itemTextAppearance="?android:attr/textAppearance"
or for large text
app:itemTextAppearance="?android:attr/textAppearanceLarge"
This worked for me:
activity_main.xml
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:theme="#style/NavigationDrawerStyle"
app:headerLayout="#layout/navdrawer_header"
app:menu="#menu/navdrawer_menu" />
styles.xml
<style name="NavigationDrawerStyle">
<item name="android:textSize">16sp</item>
</style>
Scouring through the source code I found this layout file
/platform/frameworks/support/.../design/res/layout/design_drawer_item.xml
with the following attribute
<android.support.design.internal.NavigationMenuItemView
...
android:textAppearance="?attr/textAppearanceListItem"
Which meant all we had to do was to override the textAppearanceListItem style in our project.
res/values/styles.xml
<style name="AppTheme" ... >
...
<item name="textAppearanceListItem">#style/list_item_appearance</item>
</style>
<style name="list_item_appearance">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
</style>
I'm not totally sure what else this will affect but if anyone has a better answer I'd be happy to accept that instead!
Maybe it might help. Recently I had to do this programmatically.
I used this class:
public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;
private final float newSp;
public CustomTypefaceSpan(String family, Typeface type, float sp) {
super(family);
newType = type;
newSp = sp;
}
#Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType, newSp);
}
#Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType, newSp);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf, float sp) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTextSize(sp);
paint.setTypeface(tf);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<CustomTypefaceSpan> CREATOR = new Parcelable.Creator<CustomTypefaceSpan>() {
#Override
public CustomTypefaceSpan createFromParcel(Parcel in) {
return null;
}
#Override
public CustomTypefaceSpan[] newArray(int size) {
return new CustomTypefaceSpan[size];
}
};
}
Then I used like this:
// This is for color
SpannableString s = new SpannableString(item.getTitle().toString());
s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
// This is for typeface and size
Typeface typeFace = Functions.getTypeface(this, "Avenir");
if (typeFace != null) {
int size = 19;
float scaledSizeInPixels = size * getResources().getDisplayMetrics().scaledDensity;
CustomTypefaceSpan spanTypeFace = new CustomTypefaceSpan(item.getTitle().toString(), typeFace, scaledSizeInPixels);
s.setSpan(spanTypeFace, 0, s.length(), 0);
}
item.setTitle(s);
Hope this helps.
Goto activity_main.xml and select nav_view in design and you can change menu item text size by updating itemTextAppearance and itemTextColor like as follows
For com.google.android.material.navigation.NavigationView you should use the app namespace with your custom style:
app:itemTextAppearance="#style/NavDrawerTextStyle"
List Adapter Layout of your Navigation bar:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal"
android:background="#drawable/pressed_state">
<TextView
android:id="#+id/textView_list_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/imageView_icons"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:textColor="#color/white"
android:textSize="17sp" />
<ImageView
android:id="#+id/list_adapter_image"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:visibility="visible"
android:layout_marginRight="50dp"
android:background="#drawable/circle_orange"/>
</RelativeLayout>
<LinearLayout
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#EC1294"></LinearLayout>
</LinearLayout>
This param in RelativeLayout set the background color --> android:background="#drawable/pressed_state"
Make this "pressed_state.xml" in drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#color/light_blue" android:state_pressed="true"/>
Excuse me for my english.
Open or create values\dimens.xml
Add this code:
<dimen name="design_bottom_navigation_text_size" tools:override="true">11sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>
It should work

Textinputlayout change textcolorhint when text present

Little add: I need a way of doing it when the TextInputLayout/EditText is not focused, not between focused-not focused states
I'm looking for a way to change the textColorHint property of TextInputLayout only when the text is present in the TextInputEditText (directly from XML).
If I use that property android:textColorHint="#color/black", it changes the hint color also if the TextInputEditText is empty.
Is there a way to set two different colors for the hint in the two states?
I add a couple of images to explain better
What I want:
when text is empty
when text is filled
What I don't want:
hint has "with text" color
post scriptum: yeah, I could've used two more different colors for this example, but it should be understandable anyway :P
Suppose you take two color, lets say color1 when text is empty and color2 when text is filled, try below approach.
When Text Filled
<style name="TextAppearance.App.TextInputLayout_filled" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/color2</item>
<item name="android:textSize">#dimen/text_size_12</item>
</style>
When Text Empty
<style name="TextAppearance.App.TextInputLayout_empty" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/color1</item>
<item name="android:textSize">#dimen/text_size_12</item>
</style>
Theme
<style name="TextLabel" parent="TextAppearance.AppCompat">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">#color/color1</item>
<item name="android:textSize">#dimen/text_size_16</item>
</style>
XML for TextInputLayout
<android.support.design.widget.TextInputLayout
android:id="#+id/til_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/TextLabel"
app:hintTextAppearance="#style/TextAppearance.App.TextInputLayout_filled">
<android.support.design.widget.TextInputEditText
android:id="#+id/edt_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/first_name_caps"
android:imeOptions="actionNext"
android:maxLines="1"
android:nextFocusForward="#+id/til_last_name"
android:singleLine="true"
android:textColor="#android:color/black"/>
</android.support.design.widget.TextInputLayout>
and code
edt_first_name.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (edt_first_name.getText().toString().length() > 0){
til_first_name.setHintTextAppearance(R.style.TextAppearance_App_TextInputLayout_filled);
}else {
til_first_name.setHintTextAppearance(R.style.TextAppearance_App_TextInputLayout_empty);
}
}
});
Use style
<style name="TextInputLayout" parent="#android:style/TextAppearance">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">#color/color_hint</item>
<item name="android:textColor">#color/color_black</item>
<item name="android:fontFamily">#font/helveticaneue</item>
<!-- Label color in TRUE state and bar color FALSE and TRUE State -->
<item name="colorAccent">#color/color_hint</item>
<item name="colorControlNormal">#color/color_hint</item>
<item name="colorControlActivated">#color/color_hint</item>
<item name="colorControlHighlight">#color/color_hint</item>
</style>
use this style in xml
<android.support.design.widget.TextInputLayout
android:id="#+id/layoutFirstName"
style="#style/TextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_8sdp"
app:hintTextAppearance="#style/TextInputStyle.Hint">
<android.support.design.widget.TextInputEditText
android:id="#+id/editFirstName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/first_name"
android:imeOptions="actionDone"
android:inputType="text"
android:importantForAutofill="noExcludeDescendants"
android:theme="#style/InputTextEditTextNew" />
</android.support.design.widget.TextInputLayout>
For the TextInputEditText set the color of the hint when it is empty with this attribute:
android:textColorHint="#color/yourcolor"
when it is not empty you have to set the color of the floating hint with this style:
<style name="TextInputLayoutStyle" parent="TextAppearance.AppCompat">
<item name="colorControlNormal">#color/colornormalcolor</item>
<item name="colorControlActivated">#color/anothercolor</item>
</style>
and use it in the TextInputLayout xml:
android:theme="#style/TextInputLayoutStyle"
After some research looks like we can not achieve what we are looking for from xml layout only. To do that we definitely need to customize TextInputLayout. Then can simply use that in xml layout file wherever is required.
Here is the customized TextInputLayout
public class CustomTextInputLayout extends TextInputLayout {
public CustomTextInputLayout(Context context) {
this(context, null);
}
public CustomTextInputLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
registerFocusChangeListener();
}
private void registerFocusChangeListener() {
getEditText().setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
String text = getEditText().getText().toString();
boolean isEmpty = TextUtils.isEmpty(text);
if (!isEmpty) { // EditText is not empty, doesn't matter whether it is focused or unfocused
setHintTextAppearance(R.style.TextAppearance_Dark);
} else { // EditText is empty
setHintTextAppearance(R.style.TextAppearance_Light);
}
}
});
}
}

Change the font of my toolbar using Calligraphy

I'm using the Calligraphy lib for Android to change the fonts in my app.
The problem is with the Toolbar. I don't know how to change the font.
This is my Toolbar :
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:titleTextAppearance="#style/Toolbar.TitleText"
android:background="#drawable/background_repeat"
app:popupTheme="#style/AppTheme.PopupOverlay" />
This is the TextAppearance in my style.xml :
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="fontPath">fonts/Raleway-ExtraBoldItalic.ttf</item>
<item name="android:textSize">50sp</item>
</style>
This is not working. I can change the size of the text (in this example, 50sp is working). But impossible to change the font.
The problem is that Toolbar creates TextViews for title and subtitle programmatically inside itself.
It means that it doesn't use wrapped LayoutInflater by Calligraphy.
Instead it uses system Typefaces depending on fontFamily and fontStyle from textAppearence attribute.
But Calligraphy listens for GlobalLayout changes and tries to load style from theme.
So what I've done:
Add activity theme and customize ActionBarStyle:
<style name="ActivityTheme" parent="AppTheme.Base">
<item name="android:actionBarStyle">#style/ActionBarStyle</item>
</style>
<style name="ActionBarStyle" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="android:titleTextStyle">#style/ToolbarTitleTextAppearance</item>
</style>
<style name="ToolbarTitleTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textSize">20sp</item>
<item name="fontPath">fonts/Roboto-Medium.ttf</item>
</style>
If you don't want or cannot override toolbar theme, you can subclass Toolbar and use your custom toolbar instead of the system toolbar:
public class ToolbarPlus extends Toolbar {
public ToolbarPlus(Context context) {
super(context);
}
public ToolbarPlus(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ToolbarPlus(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void setTitle(CharSequence title) {
if (title == null) {
title = "";
}
Typeface font = TypefaceUtils.load(getResources().getAssets(), "fonts/Roboto-BoldItalic.ttf");
super.setTitle(CalligraphyUtils.applyTypefaceSpan(title, font));
}
}
Replace "fonts/Roboto-BoldItalic.ttf" with your font.
You can also use this method for subtitle by overriding public void setSubtitle(CharSequence subtitle).
There is two way you can do this
1) By using style in style.xml file AnoDest told you
2) By using xml, in this way you will get more control over view, you need to create seprate xml file called appbar.xml and include it in your view
appbar.xml file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/gradient_theme"
android:elevation="#dimen/smallPadding"
android:fitsSystemWindows="true">
<com.indussoft.lms.customUI.TextViewRobotoBold
android:id="#+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity Name"
android:textStyle="bold"
android:textSize="#dimen/okTextSize"
android:layout_gravity="center"
android:gravity="center"
android:visibility="visible"
android:textColor="#color/white" />
<TextView
android:layout_width="wrap_content"
android:text="#string/accept"
fontPath="fonts/Roboto-Bold.ttf"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
And include it in your activity view such as
<include
layout="#layout/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Nothing worked for me so this is the function that I wrote in my base activity to workaround the issue:
private void setToolBarFont() {
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
for (int i = 0; i < toolbar.getChildCount(); i++) {
final View child = toolbar.getChildAt(i);
if (child instanceof TextView) {
final TextView textView = (TextView) child;
CalligraphyUtils.applyFontToTextView(textView, TypefaceUtils.load(getAssets(), "fonts/my_font.ttf"));
}
}
}
p.s. this is an open issue on Calligraphy's GitHub page currently. Here's the link to the issue:
https://github.com/chrisjenx/Calligraphy/issues/295

TextInputLayout - Change floating label hint color in EditText in rest state

I'm using TextInputLayout with floating label hints. But In the normal state I am unable to change the hint color from white to other color. Is there a way to do this ?
<android.support.design.widget.TextInputLayout
android:id="#+id/fullNameTextLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_weight="0.75">
<EditText
android:id="#+id/etFullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:singleLine="true"
android:hint="Full Name"
android:textColor="#color/gray_dark"
android:textColorHint="#color/green"
android:textColorHighlight="#color/green" />
</android.support.design.widget.TextInputLayout>
Attaching two screen shots with the background changed.
Please add this in TextInputLayout,
app:hintTextAppearance="#style/mytext
So your layout will be like :
<android.support.design.widget.TextInputLayout
android:id="#+id/aeal_input_layout_zipcode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorHint="#color/green"
app:hintTextAppearance="#style/mytext">
<EditText
android:id="#+id/aeal_etZipCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Zipcode"
android:singleLine="true"
android:inputType="number"
android:textColor="#color/primaryTextColor" />
</android.support.design.widget.TextInputLayout>
style.xml:
<style name="mytext" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/green</item>
<item name="android:textColorHint">#color/green</item>
<item name="colorAccent">#color/green</item>
<item name="android:textSize">14sp</item>
</style>
Edited : You need to add textColorHint in TextInputLayout, and it will work properly as you needed.
It worked for me, so might help you too.
Got the same probleme and solved this with the setHintTextAppearance(int) method of TextInputLayout.
Example:
First find your TextInputLayout
android.support.design.widget.TextInputLayout textInputLayout = (TextInputLayout) view.findViewById(R.id.textInputLayout);
now do the following:
textInputLayout.setHintTextAppearance(R.style.Inactive);
in your styles.xml file you create your styles with the color for the hint color. For example
<style name="Inactive" parent="AppThemeLight">
<item name="android:textColorPrimary">#android:color/darker_gray</item>
<item name="android:textColor">#android:color/darker_gray</item>
</style>
<style name="Active" parent="AppThemeLight">
<item name="android:textColorPrimary">#android:color/black</item>
<item name="android:textColor">#android:color/black</item>
</style>
now, when you change things for example onButtonClick, you simply change your style.
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
textInputLayout.setHintTextAppearance(R.style.Active);
}
});
Keep in mind, that you also have to handle the Colors for your EditText inside your TextInputLayout.
Use this to change the hint color. -
editText.setHintTextColor(getResources().getColor(R.color.xyz));
Solution for your problem -
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3){
//do something
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
//do something
}
#Override
public void afterTextChanged(Editable arg0) {
if(arg0.toString().length() <= 0) //check if length is equal to zero
editText.setHintTextColor(getResources().getColor(R.color.xyz));
}
});
In your Style.xml you can change the color of hint
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">#3498db</item>
</style>
For more see this
try this
<android.support.design.widget.TextInputLayout
........
android:textColorHint="requiredColor"
....> to change the floating hint color and
<EditText
android:textColor="requiredColor" to change the hint color in edittxt

How can I change the NavigationView's item text size?

Google recently released the android.support.design.widget.NavigationView widget as part of the com.android.support:design:22.2.0 library, which greatly simplified (and standardises) the process of creating a NavigationDrawer.
However according to the design specs, the list item should be Roboto Medium, 14sp, 87% #000000. The NavigationView exposes no textSize or textStyle to customise this.
What are my options if I'm pedantic about maintaining the correct design specifications using the Google provided NavigationView (or customising it in any other way)?
Create new style at the file app/src/main/res/values/styles.xml
<style name="NavigationDrawerStyle">
<item name="android:textSize">20sp</item><!-- text size in menu-->
<!-- item size in menu-->
<item name="android:listPreferredItemHeightSmall">40dp</item>
<item name="listPreferredItemHeightSmall">40dp</item>
<!-- item padding left in menu-->
<item name="android:listPreferredItemPaddingLeft">8dp</item>
<item name="listPreferredItemPaddingLeft">8dp</item>
<!-- item padding right in menu-->
<item name="android:listPreferredItemPaddingRight">8dp</item>
<item name="listPreferredItemPaddingRight">8dp</item>
</style>
Add it to your main_layout.xml
<android.support.design.widget.NavigationView
...
app:theme="#style/NavigationDrawerStyle"
....>
</android.support.design.widget.NavigationView>
All params of the navigation items (which you can change) are located here (path to file ...\sdk\extras\android\support\design\res\layout\design_navigation_item.xml )
design_navigation_item.xml
<android.support.design.internal.NavigationMenuItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="#dimen/navigation_icon_padding"
android:gravity="center_vertical|start"
android:maxLines="1"
android:fontFamily="sans-serif-thin"
android:textSize="22sp"
android:textAppearance="?attr/textAppearanceListItem" />
Also you can override *.xml file (copy file from ...\sdk\extras\android\support\design\res\layout\design_navigation_item.xml), just in your app/src/main/res/layout folder create a layout named the same design_navigation_item.xml.
All layouts which can be Overriden are located here ...\sdk\extras\android\support\design\res\layout\
design_layout_snackbar.xml
design_layout_snackbar_include.xml
design_layout_tab_icon.xml
design_layout_tab_text.xml
design_navigation_item.xml
design_navigation_item_header.xml
design_navigation_item_separator.xml
design_navigation_item_subheader.xml
design_navigation_menu.xml
[UPDATE] Each version of com.android.support:design-{version} lib has different items to override.
Check all what you need in
[UPDATE 04/14/2020]
If you are using com.google.android.material.navigation.NavigationView
then open the class, and you will see:
public NavigationView(#NonNull Context context, #Nullable AttributeSet attrs) {
this(context, attrs, R.attr.navigationViewStyle);
}
So you can use attr navigationViewStyle to set your own style for the NavigationView via theme of your app:
NB: parent theme of AppTheme should be Theme.MaterialComponents
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
...
<item name="navigationViewStyle">#style/AppNavigationViewStyle</item>
...
</style>
<style name="AppNavigationViewStyle" parent="Widget.MaterialComponents.NavigationView">
<item name="itemTextAppearance">#style/AppNavigationViewItemTextAppearance</item>
</style>
<style name="AppNavigationViewItemTextAppearance" parent="#style/TextAppearance.MaterialComponents.Subtitle2">
<item name="android:textSize">18sp</item>
</style>
Just open parent theme to see all <item name attrs for override
Since Android Support Library 22.2.1, Google has changed default textSize of items in NavigationView from 16sp to 14sp, which suits Material Design guideline well. However, in some cases(for example, when you want to support Chinese language), it seems larger textSize is better. Solution is simple:
add app:theme="#style/yourStyle.Drawer" to your NavigationView in your layout.xml
in styles.xml, add android:textSize="16sp" in style yourStyle.Drawer
You can customize everything from text color to size and font in your style.xml
<style name="NavDrawerTextStyle" parent="Base.TextAppearance.AppCompat">
<item name="android:textColor">#color/colorPrimaryDark</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
</style>
and then in your NavigationView:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.NavigationView
...
android:itemTextAppearance="#style/NavDrawerTextStyle"
/>
you can use this attributes inside xml file
app:itemTextAppearance="?android:attr/textAppearanceMedium"
or for small text
app:itemTextAppearance="?android:attr/textAppearance"
or for large text
app:itemTextAppearance="?android:attr/textAppearanceLarge"
This worked for me:
activity_main.xml
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:theme="#style/NavigationDrawerStyle"
app:headerLayout="#layout/navdrawer_header"
app:menu="#menu/navdrawer_menu" />
styles.xml
<style name="NavigationDrawerStyle">
<item name="android:textSize">16sp</item>
</style>
Scouring through the source code I found this layout file
/platform/frameworks/support/.../design/res/layout/design_drawer_item.xml
with the following attribute
<android.support.design.internal.NavigationMenuItemView
...
android:textAppearance="?attr/textAppearanceListItem"
Which meant all we had to do was to override the textAppearanceListItem style in our project.
res/values/styles.xml
<style name="AppTheme" ... >
...
<item name="textAppearanceListItem">#style/list_item_appearance</item>
</style>
<style name="list_item_appearance">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
</style>
I'm not totally sure what else this will affect but if anyone has a better answer I'd be happy to accept that instead!
Maybe it might help. Recently I had to do this programmatically.
I used this class:
public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;
private final float newSp;
public CustomTypefaceSpan(String family, Typeface type, float sp) {
super(family);
newType = type;
newSp = sp;
}
#Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType, newSp);
}
#Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType, newSp);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf, float sp) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTextSize(sp);
paint.setTypeface(tf);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<CustomTypefaceSpan> CREATOR = new Parcelable.Creator<CustomTypefaceSpan>() {
#Override
public CustomTypefaceSpan createFromParcel(Parcel in) {
return null;
}
#Override
public CustomTypefaceSpan[] newArray(int size) {
return new CustomTypefaceSpan[size];
}
};
}
Then I used like this:
// This is for color
SpannableString s = new SpannableString(item.getTitle().toString());
s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
// This is for typeface and size
Typeface typeFace = Functions.getTypeface(this, "Avenir");
if (typeFace != null) {
int size = 19;
float scaledSizeInPixels = size * getResources().getDisplayMetrics().scaledDensity;
CustomTypefaceSpan spanTypeFace = new CustomTypefaceSpan(item.getTitle().toString(), typeFace, scaledSizeInPixels);
s.setSpan(spanTypeFace, 0, s.length(), 0);
}
item.setTitle(s);
Hope this helps.
Goto activity_main.xml and select nav_view in design and you can change menu item text size by updating itemTextAppearance and itemTextColor like as follows
For com.google.android.material.navigation.NavigationView you should use the app namespace with your custom style:
app:itemTextAppearance="#style/NavDrawerTextStyle"
List Adapter Layout of your Navigation bar:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal"
android:background="#drawable/pressed_state">
<TextView
android:id="#+id/textView_list_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/imageView_icons"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:textColor="#color/white"
android:textSize="17sp" />
<ImageView
android:id="#+id/list_adapter_image"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:visibility="visible"
android:layout_marginRight="50dp"
android:background="#drawable/circle_orange"/>
</RelativeLayout>
<LinearLayout
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#EC1294"></LinearLayout>
</LinearLayout>
This param in RelativeLayout set the background color --> android:background="#drawable/pressed_state"
Make this "pressed_state.xml" in drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#color/light_blue" android:state_pressed="true"/>
Excuse me for my english.
Open or create values\dimens.xml
Add this code:
<dimen name="design_bottom_navigation_text_size" tools:override="true">11sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>
It should work

Categories

Resources