Navigation Drawer using RecyclerView Part - 2

In Part 1, we created a navigation drawer without header. Now it's time to setup the header and click events.




For adding header we can use different item types for our RecyclerView Items. We will use different layout for the header item and the menu items.

Let's have a look at our Adapter code, if you see the   onCreateViewHolder   method, you can see there is second parameter called itemType. That's what determines what layout to use during the view holder creation.

Let's start by creating layout for our header view.


<?xml version="1.0" encoding="utf-8"?>  
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:orientation="vertical" android:layout_width="match_parent"  
   android:layout_height="200dp"  
   android:background="@drawable/headerbg">  
   <TextView  
     android:id="@+id/headerText"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:textColor="@android:color/white"  
     android:layout_gravity="center"  
     android:paddingTop="100dp"  
     android:textSize="20sp"  
     android:text="Header"/>  
 </LinearLayout> 

Here we added just a textview to header and background image. You can download image from here.


Then, define our view types in our Adapter class. We will have two item types as follows.


   public final static int TYPE_HEADER = 0;  
   public final static int TYPE_MENU = 1; 

Since the LayoutManager needs to know how menu items the RecyclerView has,  add 1 to the getCount method as we are adding a headerView.


   @Override  
   public int getItemCount() {  
     return drawerMenuList.size()+1;  
   }  

And, let the LayoutManager know which item type is the header. We can do so by overriding getItemViewType method. We will have TYPE_HEADER at position 0 and rest of the items will be TYPE_MENU.


  @Override  
   public int getItemViewType(int position) {  
     if(position == 0){  
       return TYPE_HEADER;  
     }  
     return TYPE_MENU;  
   }  

Next we change our onCreateViewHolder class to have to different layouts based on view type.



  @Override  
   public DrawerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
     View view;  
     if(viewType == TYPE_HEADER){  
       view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_drawer_header, parent, false);  
     }else{  
       view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_menu_item, parent, false);  
     }  
     return new DrawerViewHolder(view, viewType);  
   }  

Here, we used layout_drawer_header for header type and layout_menu_item for normal menu items.
We also changed the constructor of DrawerViewHolder to accept the viewType as second parameter. So modify ViewHolder as below.


 class DrawerViewHolder extends RecyclerView.ViewHolder{  
     TextView title;  
     TextView headerText;  
     ImageView icon;  
     public DrawerViewHolder(View itemView, int viewType) {  
       super(itemView);  
       if(viewType == 0){  
         headerText = (TextView)itemView.findViewById(R.id.headerText);  
       }else {  
         title = (TextView) itemView.findViewById(R.id.title);  
         icon = (ImageView) itemView.findViewById(R.id.icon);  
       }  
     }  
   }  


Then, change onBindViewHolder method as below for setting up some Text to the TextView.


  @Override  
   public void onBindViewHolder(DrawerViewHolder holder, int position) {  
     if(position == 0) {  
       holder.headerText.setText("Header Text");  
     }else{  
       holder.title.setText(drawerMenuList.get(position - 1).getTitle());  
       holder.icon.setImageResource(drawerMenuList.get(position - 1).getIcon());  
     }  
   } 

Here we are using "position-1" to access the menu list items that's because we have added the header in the first position so the positions of the menu list and the adapter are not in sync.

And that's all, run the project and see we have a header on top of the menu items.



Finally, add click events to the menu items. For this let's write an OnItemSelectedListener interface with a method onItemSelected.


public interface OnItemSelecteListener{  
     public void onItemSelected(View v, int position);  
   } 

Then create a setOnClicklistener method in the adapter which will help us to set Listener from MainActivity. Create a field mListener of type OnItemSelecteListener and write following method.



public void setOnItemClickLister(OnItemSelecteListener mListener) {  
     this.mListener = mListener;  
   }  

Modify, DrawerViewHolder adding OnClickListener to the itemView so that whenever the itemView is clicked we can pass the clicked position through onItemSelectedMethod.


class DrawerViewHolder extends RecyclerView.ViewHolder{  
     TextView title;  
     TextView headerText;  
     ImageView icon;  
     public DrawerViewHolder(View itemView, int viewType) {  
       super(itemView);  
       if(viewType == 0){  
         headerText = (TextView)itemView.findViewById(R.id.headerText);  
       }else {  
         title = (TextView) itemView.findViewById(R.id.title);  
         icon = (ImageView) itemView.findViewById(R.id.icon);  
       }  
       itemView.setOnClickListener(new View.OnClickListener() {  
         @Override  
         public void onClick(View view) {  
           mListener.onItemSelected(view, getAdapterPosition());  
         }  
       });  
     }  
   }  

Set OnItemSelectedListener to the adapter form activity to perform various actions when menu items are selected. For now let's just show the Toasts. (Be careful about the positions if you have additional types added, for example now we have a header type added so we will have first menu at position 1 instead of 0)



 adapter.setOnItemClickLister(new DrawerAdapter.OnItemSelecteListener() {  
       @Override  
       public void onItemSelected(View v, int position) {  
         Toast.makeText(MainActivity.this, "You clicked at position: "+ position, Toast.LENGTH_SHORT).show();  
       }  
     }); 

Let's run the project.





We built navigation drawer using RecyclerView. You can find the full source code for this tutorial on github.



6 comments: Leave Your Comments

  1. I tried to change the color of link in onClick but when I click another link the changed color of previously clicked link does not restores.

    ReplyDelete
    Replies
    1. Well for that you will have to set color for both clicked item and other items. If you are using 'if' clause for checking currently selected items make sure you are use 'else' also to restore the color of other items.

      But using NavigationVIew it will be easier. http://blog.technoguff.com/2015/07/navigation-view-support-design-library.html. you can just use navigationView.setCheckedItem(id);

      Delete
  2. how can divide list items into groups

    ReplyDelete
  3. thanks a lot for the code...
    u dnt know that since 1 month i'm finding for this..

    very good explanation

    ReplyDelete
  4. its work but i cant click behind the navigation drawer

    ReplyDelete

More

Download