如何在 DrawerLayout 的 NavigationView 中设置未读通知计数?
how to set unread notification count in NavigationView of DrawerLayout?
我创建了一个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
<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
项上设置未读通知计数器?
NavigationView
旨在成为实现符合 Material 设计指南的基本导航抽屉的简单方法。
如果您想要的不仅仅是基本的抽屉式导航栏(即带有文本导航项和可选 header 的抽屉式导航栏),您需要为抽屉式导航栏创建自己的布局。
我建议您删除 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>
然后为片段创建一个 class 并为 class 创建一个资源文件,其中将包含抽屉的元素,即
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);
...
然后您可以将此片段添加到主 activity 即
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);
"set up" 方法位于片段中,这是您初始化它的地方,即
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">
在此垂直相对布局中,为元素添加另一个相对布局。这将是您添加 "Alerts" 部分的地方,如您发布的图片所示。这个相对布局应该是水平的,即
<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 中)在导航抽屉片段 class 中获取对它的引用,并用你的计数器填充它。
希望对您有所帮助!
更新后的答案:
将 app:actionLayout
与支持库 23.1.1 或更高版本一起使用将支持如下自定义布局。
创建您的自定义柜台布局,如下所示。
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 的抽屉菜单项中引用它。
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"
/>
注意应该使用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
。
上一个答案(旧版本):
通过 NavigationView
中的 ListView
解决,如下代码...
<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>
在您的 activity 设置列表项如下...
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) {
}
}
}
菜单适配器..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;
}
}
我相信在设计库的 23 中添加了对此的支持。
在您的菜单 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>
然后让包含布局的菜单计算未读项目,可能使用自定义视图或片段来获取数据。
我在这个网站上发现了这个易于实施的解决方案https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9按照以下步骤操作
第 1 步:
创建一个 Android Studio 项目,而不是选择空 activity select “Navigation Drawer Activity”。
第 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 步: 声明 Navigation Drawer 菜单项并使用徽章值初始化该项目。在您的主 Activity 中,声明导航抽屉的菜单项,如下所示
//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
我创建了一个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
<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
项上设置未读通知计数器?
NavigationView
旨在成为实现符合 Material 设计指南的基本导航抽屉的简单方法。
如果您想要的不仅仅是基本的抽屉式导航栏(即带有文本导航项和可选 header 的抽屉式导航栏),您需要为抽屉式导航栏创建自己的布局。
我建议您删除 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>
然后为片段创建一个 class 并为 class 创建一个资源文件,其中将包含抽屉的元素,即
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);
...
然后您可以将此片段添加到主 activity 即
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);
"set up" 方法位于片段中,这是您初始化它的地方,即
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">
在此垂直相对布局中,为元素添加另一个相对布局。这将是您添加 "Alerts" 部分的地方,如您发布的图片所示。这个相对布局应该是水平的,即
<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 中)在导航抽屉片段 class 中获取对它的引用,并用你的计数器填充它。
希望对您有所帮助!
更新后的答案:
将 app:actionLayout
与支持库 23.1.1 或更高版本一起使用将支持如下自定义布局。
创建您的自定义柜台布局,如下所示。
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 的抽屉菜单项中引用它。
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"
/>
注意应该使用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
。
上一个答案(旧版本):
通过 NavigationView
中的 ListView
解决,如下代码...
<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>
在您的 activity 设置列表项如下...
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) {
}
}
}
菜单适配器..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;
}
}
我相信在设计库的 23 中添加了对此的支持。
在您的菜单 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>
然后让包含布局的菜单计算未读项目,可能使用自定义视图或片段来获取数据。
我在这个网站上发现了这个易于实施的解决方案https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9按照以下步骤操作
第 1 步: 创建一个 Android Studio 项目,而不是选择空 activity select “Navigation Drawer Activity”。
第 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 步: 声明 Navigation Drawer 菜单项并使用徽章值初始化该项目。在您的主 Activity 中,声明导航抽屉的菜单项,如下所示
//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