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

11

73

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.

Material design specs Font style info

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

Armory answered 3/7, 2015 at 10:17 Comment(3)
Do you know how/ if we can replace these icons with awsomeFont icons ?Rashidarashidi
lol @ totally unrelated question! Sorry not that I know of besides downloading the PNGs and using them. You can download the material design compliant ones anyway straight from Google via google.com/design/iconsArmory
Please, check this comment linkPavlodar
S
63

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:

  1. add app:theme="@style/yourStyle.Drawer" to your NavigationView in your layout.xml
  2. in styles.xml, add android:textSize="16sp" in style yourStyle.Drawer
Synchroscope answered 18/7, 2015 at 12:59 Comment(1)
So it looks like a bug then! Cool stuff! If anyone is stuck on 22.2.0 for some reason, please see my answer.Armory
P
122

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

enter image description here

[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

Pericardium answered 24/9, 2015 at 13:0 Comment(2)
are you suggesting to override all these xmls and make my own or just use those parameters and put it in the style? Also is there any way I can specify my own font for this?Escolar
This is the kind of responde I needed, adding custom style for this values helps a lot. Thanks.Tarsometatarsus
P
66

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

Perrins answered 25/10, 2015 at 4:37 Comment(5)
How do I set roboto-medium font for the item title?Cowley
I have a navigation header as well and changing the textSize changes the size of the texts for the menu items but changing the textColor changes the colour of the text for the header. <style name="NavigationDrawer" > <item name="android:textSize">20sp</item> <item name="android:textColor">@color/white</item> </style> I wanted to change the colour of the texts for the menu items. Any idea?Snotty
This actually works but in case of if we want to apply custom ttf then how to do that?Nevins
@ojonugwaochalifu Can we set layout_gravity to position items centre_horizontal?Beaird
Hey, this worked for me when I changed android:itemTextAppearance="@style/NavDrawerTextStyle"/> to app:itemTextAppearance="@style/NavDrawerTextStyle"/>Saltation
S
63

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:

  1. add app:theme="@style/yourStyle.Drawer" to your NavigationView in your layout.xml
  2. in styles.xml, add android:textSize="16sp" in style yourStyle.Drawer
Synchroscope answered 18/7, 2015 at 12:59 Comment(1)
So it looks like a bug then! Cool stuff! If anyone is stuck on 22.2.0 for some reason, please see my answer.Armory
S
19

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"
Silhouette answered 18/9, 2016 at 21:42 Comment(0)
I
16

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>
Injury answered 18/8, 2015 at 9:43 Comment(0)
A
10

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!

Armory answered 3/7, 2015 at 11:47 Comment(1)
sans-serif-medium option is not available for meCowley
A
3

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.

Ault answered 28/6, 2017 at 7:46 Comment(1)
Thank you, although not for the solution per se, but for the example for implementing the Parcelable.Creator method.Lifelong
H
2

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 navigation_view_item_style

Herdsman answered 17/5, 2019 at 3:26 Comment(0)
A
2

For com.google.android.material.navigation.NavigationView you should use the app namespace with your custom style: app:itemTextAppearance="@style/NavDrawerTextStyle"

Astrograph answered 29/3, 2021 at 14:50 Comment(1)
Thanks Perfect answer.Nightie
I
0

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.

Ironsides answered 3/7, 2015 at 10:56 Comment(3)
hey thanks a lot for your answer, however I came from implementing my own navdrawer to using the support one from Google. I was hoping to achieve this using NavigationView itself.Armory
dude you have to make a layout as you like to put there in your adapter.Ironsides
I think we're implementing the nav drawer differently. I'm not sure what you mean by "List Adapter Layout". With the design support library's NavigationView there's no list adapters at play but app:menu="@menu/drawer" referencing a standard menu. See the first snippet of goo.gl/D0kVBH for more details. Apologies if I'm understanding you wrong :)Armory
G
0
  1. Open or create values\dimens.xml
  2. 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

Galloping answered 6/12, 2018 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.