how to set unread notification count in NavigationView of DrawerLayout?

I have created one NavigationView inside DrawerLayout using Android Design Support Library

 <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">

     <!-- other views -->

     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/my_navigation_items" />
 </android.support.v4.widget.DrawerLayout>

my_navigation_items.xml

  • Android link to wireless & Network Settings
  • Using Make's 'wildcard' function in Android.mk
  • Android addHeaderView disappears when no items in ListView
  • How to disable/enable network, switch to Wifi in Android emulator?
  • Genymotion: how to load apk every time?
  • Android List with section headers
  • <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/bookmarks_drawer"
                android:icon="@drawable/ic_drawer_bookmarks"
                android:title="@string/bookmarks" />
            <item
                android:id="@+id/alerts_drawer"
                android:icon="@drawable/ic_drawer_alerts"
                android:title="@string/alerts" />
            <item
                android:id="@+id/settings_drawer"
                android:icon="@drawable/ic_drawer_settings"
                android:title="@string/settings" />
        </group> 
    </menu>
    

    Now, I want to set unread notification counter for each item of NavigationView like below image:

    unread notification counter

    how to set unread notification counter on item of NavigationView ?

    Related posts:

    Android navigation bar size in xml
    Determining Long Tap (Long Press, Tap Hold) on Android with jQuery
    How to get current timestamp of firebase server in milliseconds?
    gradle - Android Studio build too slow multidex application
    Android valgrind build fails
    writing .json file and read that file in Android
  • How do you remove an inflated menu/items from the new Lollipop Toolbar?
  • Removing the left padding on an Android EditText
  • Material Design - What does 'use the tint 700' mean?
  • Drag and drop items in RecyclerView with GridLayoutManager
  • VideoView black flash before and after playing
  • android library project and Activities
  • 5 Solutions collect form web for “how to set unread notification count in NavigationView of DrawerLayout?”

    Updated answer:

    Using app:actionLayout with support library 23.1.1 or higher will support the custom layout as below.

    Create your custom counter layout like below.

    menu_counter.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    

    Reference it in your drawer menu item in xml.

    menu/drawer.xml:

    <item
        android:id="@+id/navigation_drawer_item_1"
        android:icon="@drawable/ic_menu_1"
        android:title="@string/navigation_drawer_item_1"
        app:actionLayout="@layout/menu_counter"
        />
    

    Note that you should use app namespace, don’t try to use android.

    Alternatively you can manually set action view with MenuItem.setActionView() method.

    Find menu item and set counter like below code:

    private void setMenuCounter(@IdRes int itemId, int count) {
        TextView view = (TextView) navigationView.getMenu().findItem(itemId).getActionView();
        view.setText(count > 0 ? String.valueOf(count) : null);
    }
    

    Note, that you will need to use MenuItemCompat if you have to support Android 2.x versions.

    Previous Answer (For older version) :

    Solved with ListView inside NavigationView as below code…

    <android.support.design.widget.NavigationView
        android:id="@+id/my_courses_nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header" >
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="150dp" > <!-- Give layout margin top according to "headerLayout" height -->
    
            <ListView
                android:id="@+id/left_drawer"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white"
                android:cacheColorHint="@android:color/transparent"
                android:choiceMode="singleChoice"
                android:divider="@android:color/transparent"
                android:dividerHeight="0dp" />
    
        </FrameLayout>
    </android.support.design.widget.NavigationView>
    

    In your activity set list item as below…

        private final String[] mMenuTitles = { getResources().getString(R.string.bookmarks), getResources().getString(R.string.alerts), getResources().getString(R.string.settings)  };
        private final int[] mMenuIconId = { R.drawable.ic_drawer_bookmarks, R.drawable.ic_drawer_alerts, R.drawable.ic_drawer_settings };
    
    
        ListView mDrawerList = (ListView) findViewById(R.id.left_drawer);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    
        private ArrayList<SlideMenuItem> drawerItemList = new ArrayList<SlideMenuItem>();           
        for( int i = 0; i < mMenuTitles.length; i++ ) {
            SlideMenuItem item = new SlideMenuItem();
            item.setTitle(mMenuTitles[i]);
            item.setIconID(mMenuIconId[i]);
            // item..setUnread(5) //set or update unread count & notify dataset changed to adapter
            drawerItemList.add(item);
        }
    
        MenuAdapter mMenuAdapter = new MenuAdapter( MyCoursesActivity.this, R.layout.drawer_list_item, drawerItemList);
        mDrawerList.setAdapter(mMenuAdapter);
    

    The click listener for ListView in the navigation drawer…

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            try {
                mDrawerLayout.closeDrawers();
                SlideMenuItem item =  (SlideMenuItem) parent.getItemAtPosition(position);
                switch (item.getIconId()) {
    
                    case R.drawable.ic_drawer_bookmarks: {
    
                    }
                    break;
                    case R.drawable.ic_drawer_alerts: {
    
                    }
                    break;
                    case R.drawable.ic_drawer_settings: {
    
                    }
                    break;                  
                    default: {
                    }
                    break;
                }
            } catch (Exception e) {             
            }
    
        }
    }
    

    MenuAdapter..java

    public class MenuAdapter extends ArrayAdapter<SlideMenuItem> {
    
    private Activity activity;
    private List<SlideMenuItem> itemList;
    private SlideMenuItem item;
    private int row;
    
    public MenuAdapter(Activity act, int resource, List<SlideMenuItem> arrayList) {
        super(act, resource, arrayList);
        this.activity = act;
        this.row = resource;
        this.itemList = arrayList;
    }
    
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = convertView;
        ViewHolder holder;
        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(row, null);
    
            holder = new ViewHolder();
            holder.tvTitle = (TextView) view.findViewById(R.id.menu_title);
            holder.imgView = (ImageView) view.findViewById(R.id.menu_icon);
            holder.tvUnread = (TextView) view.findViewById(R.id.unread_count);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
    
        if ((itemList == null) || ((position + 1) > itemList.size()))
            return view;
    
        item = itemList.get(position);
    
        holder.tvTitle.setText(item.getTitle());
        holder.imgView.setImageResource(item.getIconId());
        if( item.getUnreadCount() > 0 ) {
            holder.tvUnread.setVisibility(View.VISIBLE);
            holder.tvUnread.setText(item.getUnread());
            if( MyCoursesActivity.DRAWER_MENU_ALERTS_POSITION == position ) {
                holder.tvUnread.setBackgroundResource(R.drawable.round_unread_count_bg_red);    
            }
            else {
                holder.tvUnread.setBackgroundResource(R.drawable.round_unread_count_bg_green);
            }
        }
        else {
            holder.tvUnread.setVisibility(View.GONE);
        }
        return view;
    }
    
    public class ViewHolder {
    
        public TextView tvTitle;
        public ImageView imgView;
        public TextView tvUnread;
    }
    
    }
    

    drawer_list_item.xml

    <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:id="@+id/drawar_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <ImageView
        android:id="@+id/menu_icon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:gravity="center_vertical"
        android:src="@drawable/ic_drawer" />
    
    <TextView
        android:id="@+id/menu_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/unread_count"
        android:layout_toRightOf="@+id/menu_icon"
        android:minHeight="?attr/listPreferredItemHeightSmall"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:text="About Us"
        android:gravity="center_vertical"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@android:color/black" />
    
    <TextView
        android:id="@+id/unread_count"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignParentRight="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:gravity="center" 
        android:text="99+"
        android:textColor="@android:color/white"
        android:textSize="10sp"
        android:visibility="gone" />
    

    SlideMenuItem.java

    public class SlideMenuItem {
    
    private Bitmap icon;
    private String title;
    private String unread;
    private int iconID;
    
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    public Bitmap getIcon() {
        return icon;
    }
    
    public void setIcon(Bitmap icon) {
        this.icon = icon;
    }
    
    public int getIconId() {
        return iconID;
    }
    
    public void setIconID(int icon) {
        this.iconID = icon;
    }
    
    public String getUnread() {
        return unread;
    }
    
    public int getUnreadCount() {
        int count = Flinnt.INVALID;
        try {
            if( null != unread ) {
                count = Integer.parseInt(unread);
            }
        } catch (Exception e) {
        }
        return count;
    }
    
    public void setUnread(String unread) {
        this.unread = unread;
    }
    
    }
    

    NavigationView is designed to be an easy way to implement a basic navigation drawer that is compliant with the Material design guidelines.

    If you want anything more than a basic navigation drawer (i.e. one with text navigation items and an optional header), you will need to create your own layout for your navigation drawer.

    I would suggest you remove the NavigationView and add the navigation drawer elements as a fragment i.e. in the DarawerLayout file

    <android.support.v4.widget.DrawerLayout    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"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <LinearLayout
    

    <fragment
        android:id = "@+id/fragment_navigation_drawer"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity = "start"
        android:layout= "@layout/fragment_navigation_drawer"
        android:name="com.your_package.NavigationDrawerFragment"
        tools:layout="@layout/fragment_navigation_drawer" />
    
    </android.support.v4.widget.DrawerLayout>
    

    Then create a class for the fragment and create a resource file for the class that will contain the elements for your drawer i.e.

    public class NavigationDrawerFragment extends Fragment {
    ...
    
    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
    ...
    

    You can then add this fragment to your main activity i.e.

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        navigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
        navigationDrawerFragment.setUp(R.id.fragment_navigation_drawer,mDrawerLayout, toolbar);
    

    the “set up” method is located in the fragment and that’s where you initialize it i.e.

    public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
    
        containerView = getActivity().findViewById(fragmentId);
        mDrawerLayout = drawerLayout;
        mActionBarDrawerToggle = new ActionBarDrawerToggle(
                getActivity(), mDrawerLayout, toolbar,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close
        ) {
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
    
                }
                getActivity().invalidateOptionsMenu();
    
            }
    
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
    
    
            }
    
    }
    

    In the layout file for the drawer, add the elements you want to set the unread notification for then add a relative layout whose orientation you’ll set to vertical i.e.

    <RelativeLayout
        android:layout_below="@+id/drawer_layout_unread_notif"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="fill_parent">
    

    Within this vertical relative layout, add another relative layout for the elements. This would be the place you’d add the “Alerts” section as in the image you posted. This relative layout should be horizontal i.e.

    <RelativeLayout
            android:layout_below="@+id/drawer_items_1"
            android:orientation="horizontal"
            android:background="@drawable/drawer_selector"
            android:clickable="true"
            android:layout_width="match_parent"
            android:id="@+id/drawer_items_2"
            android:layout_height="48dp">
    
            <ImageView
                android:src="@drawable/ic_notification"
                android:padding="8dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:layout_centerVertical="true"
                android:layout_gravity="center_vertical"/>
    
            <TextView
                android:text="Notifications"
                android:textColor="@color/primary_text"
                android:layout_marginLeft="72dp"
                android:layout_centerVertical="true"
                android:layout_gravity="center_vertical"
                android:padding="8dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    
            <TextView
                android:background="@color/red"
                android:layout_marginRight="10dp"
                android:id="@+id/drawer_notifications"
                android:layout_alignParentRight="true"
                android:padding="8dp"
                android:layout_centerVertical="true"
                android:textColor="@color/white"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    
    
        </RelativeLayout>
    

    The last textview element in the code just above this will contain the counter you want to add for unread notifications. In the xml its color is set to red. From here, get a reference to it in the Navigation drawer fragment class using its ID (in oncreateview) and populate it with your counter.

    Hope this helps!

    Support for this was added in 23 of the design library, I believe.

    In your menu XML file, set a actionLayout in the app XML prefix:

    <menu 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"
    tools:context="com.example.user.myapplication.MainActivity" >
        <item android:id="@+id/menu_one"
            android:checkable="true"
            android:title="Unread items"
            app:actionLayout="@layout/unread_items"
            />
    </menu>
    

    Then have the menu included layout calculate the unread items, probably using a custom view or fragment to fetch the data.

    I found this easy to implement solution on this web site https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9 Follow the steps below

    Step 1:
    Create an Android Studio project, instead of choosing empty activity select “Navigation Drawer Activity”.

    Step 2:
    Adding “actionViewClass” attribute to the navigation drawer menu (i.e. menu/youractivityname_drawer.xml)

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_camera"
            android:icon="@drawable/ic_menu_camera"
            android:title="Import" />
        <item
            android:id="@+id/nav_gallery"
            app:actionViewClass="android.widget.TextView"
            android:icon="@drawable/ic_menu_gallery"
            android:title="Gallery" />
        <item
            android:id="@+id/nav_slideshow"
            app:actionViewClass="android.widget.TextView"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="Slideshow" />
        <item
            android:id="@+id/nav_manage"
            android:icon="@drawable/ic_menu_manage"
            android:title="Tools" />
    </group>
    

    Step 3 : Declare the Navigation Drawer menu item and initialize the item with the badge value. In your main Activity, declare the menu item of the Navigation Drawer as given below

    //Create these objects above OnCreate()of your main activity
    TextView slideshow,gallery;
    
    //These lines should be added in the OnCreate() of your main activity
     NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
     navigationView.setNavigationItemSelectedListener(this);
    
    gallery=(TextView) MenuItemCompat.getActionView(navigationView.getMenu().
            findItem(R.id.nav_gallery));
    
    slideshow=(TextView) MenuItemCompat.getActionView(navigationView.getMenu().
            findItem(R.id.nav_slideshow));
    
    //This method will initialize the count value
    initializeCountDrawer();
    

    Step 5:
    Initialize initializeCountDrawer() where ever it’s required. It can also be used to update the count or badge value in the navigation drawer menu item.

    private void initializeCountDrawer(){
    
       //Gravity property aligns the text
       gallery.setGravity(Gravity.CENTER_VERTICAL);
       gallery.setTypeface(null, Typeface.BOLD);
       gallery.setTextColor(getResources().getColor(R.color.colorAccent));
       gallery.setText("99+");
       slideshow.setGravity(Gravity.CENTER_VERTICAL);
       slideshow.setTypeface(null,Typeface.BOLD);                                                                                                                    slideshow.setTextColor(getResources().getColor(R.color.colorAccent));
      //count is added     
      slideshow.setText("7");
    }
    

    Source: https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.