如何在DrawViewLayout的NavigationView中设置未读的通知计数?

我使用Androiddevise支持库在DrawerLayout中创build了一个NavigationView

<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

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

现在,我想为每个NavigationView项目设置未读通知计数器,如下图所示:

未读通知柜台

如何在NavigationView项目上设置未读的通知计数器?

更新回答:

使用支持库23.1.1或更高版本的app:actionLayout将支持如下的自定义布局。

像下面创build您的自定义计数器布局。

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

在xml的抽屉菜单项中引用它。

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

请注意,您应该使用app命名空间,不要尝试使用android

或者,您可以使用MenuItem.setActionView()方法手动设置操作视图。

查找菜单项并设置计数器,如下面的代码:

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

请注意,如果您必须支持Android 2.x版本,则需要使用MenuItemCompat

以前的答案(对于旧版本):

解决与ListView内的NavigationView作为下面的代码…

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

在您的活动集列表项目如下…

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

导航抽屉中的ListView的点击监听器…

 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被devise成一个简单的方法来实现一个符合材料devise指南的基本导航抽屉。

如果你想要的不只是一个基本的导航抽屉(例如一个带有文本导航项目和一个可选的标题),你将需要为你的导航抽屉创build自己的布局。

我build议你删除NavigationView并添加导航抽屉元素作为一个片段,即在DarawerLayout文件

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

然后为该片段创build一个类,并为该类创build一个资源文件,该文件将包含您的抽屉的元素即

 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); ... 

然后你可以将这个片段添加到你的主要活动,即

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

“设置”方法位于片段,这就是你初始化的地方,即

 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); } } 

在抽屉的布局文件中,添加要设置未读通知的元素,然后添加一个相对布局,其方向将设置为垂直

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

在此垂直相对布局中,为元素添加另一个相对布局。 这将是您添加“警报”部分的地方,就像您发布的图片一样。 这个相对布局应该是水平的,即

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

刚才在上面代码中的最后一个textview元素将包含你想添加未读通知的计数器。 在xml中,它的颜色设置为红色。 从这里,在导航抽屉碎片类中使用其ID(在oncreateview中)获取对它的引用,并用您的计数器填充它。

希望这可以帮助!

我相信在devise库中增加了对此的支持。

在您的菜单XML文件中,在app XML前缀中设置一个actionLayout

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

然后让菜单包含布局计算未读项目,可能使用自定义视图或片段来获取数据。

我发现这个网站很容易实现解决schemehttps://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9按照下面的步骤

第1步:创build一个Android Studio项目,而不是select空的活动select“导航抽屉活动”。

第2步:添加“actionViewClass”属性到导航抽屉菜单(即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> 

步骤3:声明“导航抽屉”菜单项并使用标​​记值初始化项目。 在您的主要活动中,声明如下所示的导航抽屉的菜单项

 //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(); 

第5步:初始化initializeCountDrawer(),只要它是必需的。 它也可用于更新导航抽屉菜单项中的计数或标记值。

 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"); } 

资料来源: https : //android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9