21

Ho creato uno NavigationView all'interno DrawerLayout utilizzando Android Design Support Librarycome impostare il conteggio delle notifiche non lette in NavigationView di DrawerLayout?

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

Ora, voglio impostare contatore di notifica non letto per ogni voce di NavigationView come qui di seguito immagine:

unread notification counter

come impostare il contatore delle notifiche non lette su articolo di NavigationView?

+1

Con la lettura del codice decompilato NavigationView (non riusciva a trovare originale ...), sembra che non c'è modo di fare questo con NavigationView. Dovresti implementare il tuo. – Zharf

+0

http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/ questo è il miglior esempio per la tua domanda – impathuri

+1

@SatishPathuri ti sto chiedendo come farlo usando 'NavigationView'? Nel tuo link non sta usando 'NavigationView'. –

risposta

41

risposta Aggiornato:

Utilizzando app:actionLayout con libreria di supporto 23.1.1 o superiore sosterrà il layout personalizzato come di seguito.

Crea il tuo layout contatore personalizzato come di seguito.

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

di riferimento nella vostra voce di menu cassetto in XML.

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

nota che si dovrebbe usare app spazio dei nomi, non cercare di usare android.

In alternativa è possibile impostare manualmente la vista di azione con il metodo MenuItem.setActionView().

voce di menu Trova e contro incastonato come sottostante Codice:

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

nota, che sarà necessario utilizzare MenuItemCompat se si deve sostenere Android 2.x versioni.

risposta

precedente (per la versione più vecchia):

risolto con ListView all'interno NavigationView come sottostante Codice ...

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

Nella vostra attività di impostare la voce lista come di seguito ...

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'ascoltatore dei clic per ListView nel cassetto di navigazione ...

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

} 
+0

Risposta perfetta, questo dovrebbe essere protetto – Sauron

+0

Ho bisogno di più pulsanti per votare. Solo uno non è abbastanza. Risposta fantastica! – burntblark

+0

@ burntblark Grazie amico :) –

3

NavigationView è progettato per essere un modo semplice per implementare un cassetto di navigazione di base conforme alle linee guida sulla progettazione dei materiali.

Se si desidera qualcosa di più di un semplice pannello di navigazione (ad esempio uno con elementi di navigazione testuale e un'intestazione opzionale), è necessario creare il proprio layout per il cassetto di navigazione.

2

vorrei suggerire di rimuovere il NavigationView e aggiungere gli elementi cassetto di navigazione come un frammento cioè nel DarawerLayout presentare

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

Quindi creare una classe per il frammento e creare una risorsa file per la classe che conterrà gli elementi per il tuo cassetto ie

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

È quindi possibile aggiungere questo frammento alla vostra attività principale ovvero

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

il metodo di "set up" si trova nel frammento ed è lì che si inizializza esso cioè

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


     } 

} 

Nel file di layout per la cassetto, aggiungere gli elementi che si desidera impostare la notifica non letto per poi aggiungere una disposizione relativa il cui orientamento potrai impostare per es verticale

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

All'interno di questa verticale layout relativo, aggiungi un altro layout relativo per gli elementi. Questo sarebbe il posto in cui aggiungere la sezione "Avvisi" come nell'immagine che hai pubblicato. Questa disposizione relativa deve essere orizzontale cioè

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

L'ultimo elemento TextView nel codice appena sopra questo conterrà il contatore che si desidera aggiungere per le notifiche non lette. Nel xml il suo colore è impostato su rosso. Da qui, prendi un riferimento ad esso nella classe frammento del cassetto di navigazione usando il suo ID (in oncreateview) e compilalo con il tuo contatore.

Spero che questo aiuti!

0

Il supporto per questa è stato aggiunto nel 23 della Libreria del progetto, credo.

Nel file XML del menu, impostare un actionLayout nel prefisso 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> 

Poi hanno il menu comprendeva layout di calcolare gli elementi non letti, probabilmente utilizzando una visualizzazione personalizzata o un frammento per recuperare i dati.

0

ho trovato questo facile da implementare soluzione di questo sito web https://android.jlelse.eu/android-adding-badge-or-count-to-the-navigation-drawer-84c93af1f4d9 Seguire i passaggi di seguito

Fase 1: Creare un progetto Studio Android, invece di scegliere l'attività vuota selezionare “Navigazione cassetto Activity”.

Fase 2: Aggiunta attributo “actionViewClass” al menu di navigazione cassetto (vale a dire del 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> 

Fase 3: dichiarare la voce di menu di navigazione cassetto e inizializza l'oggetto con il valore del badge. Nella vostra attività principale, dichiarare la voce di menu del cassetto di navigazione, come indicato di seguito

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

Fase 5: inizializzazione initializeCountDrawer() dove mai è richiesto. Può anche essere utilizzato per aggiornare il conteggio o il valore del badge nella voce di menu del cassetto di navigazione.

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

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