как установить количество непрочитанных уведомлений в NavigationView DrawerLayout?
Я создал один NavigationView внутри DrawerLayout используя Библиотека Поддержки Дизайна Android
<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
?
5 ответов
обновленный ответ:
используя 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.
меню/ящика.в 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);
}
обратите внимание, что вы должны использовать MenuItemCompat
если вы должны поддержать Android 2.x
версий.
предыдущий ответ (для более старой версии) :
решить 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
конструировано для того чтобы быть легким путем снабдить основной ящик навигации который уступчив с материальными директивами конструкции.
Если вам нужно что-то большее, чем базовый навигационный ящик (т. е. с элементами текстовой навигации и дополнительным заголовком), Вам нужно будет создать свой собственный макет для навигационного ящика.
Я бы предложил вам удалить 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>
затем создайте класс для фрагмент и создайте файл ресурсов для класса, который будет содержать элементы для вашего ящика, т. е.
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) и заполните его своим счетчиком.
надеюсь, что это помогает!
Я нашел это простое в реализации решение на этом веб-сайте https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9 выполните следующие действия
Шаг 1: Создайте проект Android Studio, вместо выбора пустой активности выберите "активность навигационного ящика".
Шаг 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
поддержка для этого была добавлена в 23 из библиотеки дизайна, я считаю.
в XML-файле меню установите actionLayout
на app
префикс XML:
<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>
затем в меню включен макет вычислить непрочитанные элементы, возможно, используя пользовательский вид или фрагмент для извлечения данных.