web-dev-qa-db-fra.com

comment définir le nombre de notifications non lues dans NavigationView de DrawerLayout?

J'en ai créé un NavigationView à l'intérieur DrawerLayout en utilisant 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>

Maintenant, je veux définir un compteur de notifications non lues pour chaque élément de NavigationView comme l'image ci-dessous:

unread notification counter

comment définir le compteur de notifications non lues sur l'élément de NavigationView?

26
Priyank Patel

Réponse mise à jour:

L'utilisation de app:actionLayout Avec la bibliothèque de support 23.1.1 ou supérieure prendra en charge la disposition personnalisée comme ci-dessous.

Créez votre disposition de comptoir personnalisée comme ci-dessous.

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

Référencez-le dans l'élément de menu de votre tiroir en xml.

menu/tiroir.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"
    />

Notez que vous devez utiliser app namespace, n'essayez pas d'utiliser Android.

Vous pouvez également définir manuellement la vue des actions avec la méthode MenuItem.setActionView().

Recherchez l'élément de menu et définissez le compteur comme le code ci-dessous:

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

Notez que vous devrez utiliser MenuItemCompat si vous devez prendre en charge les versions Android 2.x.

Réponse précédente (pour les anciennes versions):

Résolu avec ListView à l'intérieur NavigationView comme ci-dessous le 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>

Dans votre liste d'activités définie comme ci-dessous ...

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

L'écouteur de clic pour ListView dans le tiroir de navigation ...

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

}

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

}
54
Priyank Patel

NavigationView est conçu pour être un moyen facile d'implémenter un tiroir de navigation de base conforme aux directives de conception des matériaux.

Si vous voulez autre chose qu'un tiroir de navigation de base (c'est-à-dire avec des éléments de navigation de texte et un en-tête facultatif), vous devrez créer votre propre mise en page pour votre tiroir de navigation.

5
Tanis.7x

J'ai trouvé cette solution facile à implémenter sur ce site Web https://Android.jlelse.eu/Android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9 Suivez les étapes au dessous de

Étape 1: Créez un projet Android Studio), au lieu de choisir une activité vide, sélectionnez "Navigation Drawer Activity".

Étape 2: Ajout de l'attribut "actionViewClass" au menu du tiroir de navigation (c'est-à-dire 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>

Étape 3: Déclarez l'élément de menu Tiroir de navigation et initialisez l'élément avec la valeur du badge. Dans votre activité principale, déclarez l'élément de menu du tiroir de navigation comme indiqué ci-dessous

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

Étape 5: Initialisez initializeCountDrawer () partout où cela est nécessaire. Il peut également être utilisé pour mettre à jour le nombre ou la valeur du badge dans l'élément de menu du tiroir de navigation.

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

5
Seunope

Je vous suggère de supprimer le NavigationView et d'ajouter les éléments du tiroir de navigation en tant que fragment, c'est-à-dire dans le fichier 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>

Créez ensuite une classe pour le fragment et créez un fichier de ressources pour la classe qui contiendra les éléments de votre tiroir, c'est-à-dire.

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

Vous pouvez ensuite ajouter ce fragment à votre activité principale, c'est-à-dire.

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

la méthode "set up" est située dans le fragment et c'est là que vous l'initialisez c'est-à-dire.

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


        }

}

Dans le fichier de mise en page du tiroir, ajoutez les éléments pour lesquels vous souhaitez définir la notification non lue, puis ajoutez une mise en page relative dont vous définissez l'orientation verticale, c'est-à-dire.

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

Dans cette disposition relative verticale, ajoutez une autre disposition relative pour les éléments. Ce serait l'endroit où vous ajouteriez la section "Alertes" comme dans l'image que vous avez publiée. Cette disposition relative doit être horizontale, c'est-à-dire.

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

Le dernier élément textview dans le code juste au-dessus de celui-ci contiendra le compteur que vous souhaitez ajouter pour les notifications non lues. Dans le xml, sa couleur est définie sur rouge. À partir d'ici, obtenez une référence à celui-ci dans la classe de fragments du tiroir de navigation à l'aide de son ID (dans oncreateview) et remplissez-le avec votre compteur.

J'espère que cela t'aides!

2
Gabriel Wamunyu

Le support a été ajouté dans 23 de la bibliothèque de conception, je crois.

Dans le fichier XML de votre menu, définissez un actionLayout dans le préfixe XML app:

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

Demandez ensuite à la disposition incluse dans le menu de calculer les éléments non lus, probablement à l'aide d'une vue ou d'un fragment personnalisé pour récupérer les données.

0
newfivefour