How can I change the NavigationView's item tex

2019-01-12 22:03发布

问题:

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

回答1:

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


回答2:

create style

<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 (which you can change) are located here change the navigation items.

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:

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

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



回答3:

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
    ...
    app:itemTextAppearance="@style/NavDrawerTextStyle"
     />



回答4:

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"


回答5:

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!



回答6:

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>


回答7:

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.



回答8:

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.



回答9:

  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

P.S remove space after < before dimen