Search code examples
androidxmlandroid-layoutnavigation-drawernavigationview

How to change font size and colour in androidx drawer layout widget


See the below image I want to change the font size and color of marked footer area text which is placed in menu. I do not want to use android.support.design.widget.NavigationView, that I know I can change it by using this. Please help me.

OR

If there is any other way to add a footer area as like the same as we set the header area attribute (app:headerLayout="@layout/nav_header_main")?

Here is my main XML code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:theme="@style/menuTextStyle"
        android:background="@color/colorBlack"
        app:itemTextColor="@color/colorWhite"
        app:itemIconTint="@color/colorWhite"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

Here is activity_main_drawer.xml code:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:title="Home" />
        <item
            android:id="@+id/nav_my_pets"
            android:title="My Pets" />
        <item
            android:id="@+id/nav_my_stores"
            android:title="My Stores" />
        <item
            android:id="@+id/nav_my_products"
            android:title="My Products" />
        <item
            android:id="@+id/nav_promotions"
            android:title="Promotions" />
        <item
            android:id="@+id/nav_faqs"
            android:title="FAQs" />

        <item
            android:id="@+id/nav_account"
            android:title="My Account" />
        <item
            android:id="@+id/nav_notifications"
            android:title="Notifications" />
        <item
            android:id="@+id/nav_about"
            android:title="About" />
        <item
            android:id="@+id/nav_settings"
            android:title="Settings"
            android:visible="false" />
        <item
            android:id="@+id/nav_forum"
            android:title="Forum" />
        <item
            android:id="@+id/nav_terms"
            android:title="Privacy/Terms" />
        <item
            android:id="@+id/nav_logout"
            android:title="Logout" />
    </group>
    <group android:checkableBehavior="none">
            <item
                android:id="@+id/subtitle2"
                android:title="by:">
                <menu>
                    <item
                        android:id="@+id/nav_footer1"
                        android:checkableBehavior="none"
                        android:title="by:" />
                    <item
                        android:id="@+id/nav_footer2"
                        android:checkableBehavior="none"
                        android:title="afterdarkgrafx.com" />
                </menu>
            </item>
    </group>
</menu>

enter image description here


Solution

  • You can either use:

    // Java
    private void setMenuTextSize(MenuItem item, float proportion) {
        SpannableString spanString = new SpannableString(item.getTitle().toString());
        spanString.setSpan(new RelativeSizeSpan(proportion), 
                              0, spanString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        item.setTitle(spanString);
    }
    
    // Kotlin
    private fun setMenuTextSize(item: MenuItem, proportion: Float) {
        val spanString = SpannableString(item.title.toString())
        spanString.setSpan(
            RelativeSizeSpan(proportion),
            0, spanString.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        item.title = spanString
    }
    
    // Java
    private void setMenuTextSize(MenuItem item, int textSize) {
        SpannableString spanString = new SpannableString(item.getTitle().toString());
        spanString.setSpan(new AbsoluteSizeSpan(textSize), 0, spanString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        item.setTitle(spanString);
    }
    
    // Kotlin
    private fun setMenuTextSize(item: MenuItem, textSize: Int) {
        val spanString = SpannableString(item.title.toString())
        spanString.setSpan(
            AbsoluteSizeSpan(textSize),
            0,
            spanString.length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        item.title = spanString
    }
    

    To convert from sp to pixel:

    // Java
    public static int spToPx(int sp) {
        return (int) (sp * Resources.getSystem().getDisplayMetrics().scaledDensity);
    }
    
    // Kotlin 
    fun spToPx(sp: Int) = (sp * Resources.getSystem().displayMetrics.scaledDensity).toInt()
    

    Applying that on your menu:

    // Java
    private void reduceItemSize(NavigationView navView) {
        Menu menu = navView.getMenu();
        MenuItem item = menu.findItem(R.id.subtitle2);
        SubMenu subMenu = item.getSubMenu();
        MenuItem footer1Item = subMenu.findItem(R.id.nav_footer1);
        MenuItem footer2Item = subMenu.findItem(R.id.nav_footer2);
    
        // Using RelativeSizeSpan
        setMenuTextSize(footer1Item, 0.8f);
        setMenuTextSize(footer2Item, 0.8f);
    
        // Using AbsoluteSizeSpan
        setMenuTextSize(footer1Item, spToPx(12));
        setMenuTextSize(footer2Item, spToPx(12));
    }
    
    // Kotlin
    private fun reduceItemSize(navView: NavigationView) {
        val menu = navView.menu
        val item = menu.findItem(R.id.subtitle2)
        val subMenu = item.subMenu
        val footer1Item = subMenu.findItem(R.id.nav_footer1)
        val footer2Item = subMenu.findItem(R.id.nav_footer2)
    
        // Using RelativeSizeSpan
        setMenuTextSize(footer1Item, 0.8f)
        setMenuTextSize(footer2Item, 0.8f)
    
        // Using AbsoluteSizeSpan
        setMenuTextSize(footer1Item, spToPx(12))
        setMenuTextSize(footer2Item, spToPx(12))
    }
    

    enter image description here