Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding expandableListView to NavigationView

I have a menu defined in xml:

<group android:checkableBehavior="single" android:id="@+id/group">     <item         android:id="@+id/grades"         android:icon="@drawable/ic_font_download_black_48dp"         android:checked="false"         android:title="Grades" >         <menu>             <item                 android:id="@+id/mp1"                 android:icon="@drawable/ic_looks_one_black_24dp"                 android:checked="false"                 android:title="MP1" />             <item                 android:id="@+id/mp2"                 android:icon="@drawable/ic_looks_two_black_24dp"                 android:checked="false"                 android:title="MP2" />             <item                 android:id="@+id/mp3"                 android:icon="@drawable/ic_font_download_black_48dp"                 android:checked="false"                 android:title="MP3" />             <item                 android:id="@+id/mp4"                 android:icon="@drawable/ic_font_download_black_48dp"                 android:checked="false"                 android:title="MP4" />         </menu>     </item>     <item         android:id="@+id/schedule"         android:icon="@drawable/ic_event_black_48dp"         android:checked="false"         android:title="Schedule" />     <item         android:id="@+id/attendance"         android:icon="@drawable/ic_assignment_ind_black_48dp"         android:checked="false"         android:title="Attendance" />     <item         android:id="@+id/assignments"         android:icon="@drawable/ic_assignment_black_48dp"         android:checked="false"         android:title="Assignments" />     <item         android:id="@+id/studentInfo"         android:icon="@drawable/ic_account_circle_black_48dp"         android:checked="false"         android:title="Student Details" /> </group> <group android:id="@+id/group2" android:checkableBehavior="single">     <item         android:id="@+id/placeholder"         android:icon="@drawable/ic_android_black_48dp"         android:checked="false"         android:title="Placeholder" />     <item         android:id="@+id/placeholder2"         android:icon="@drawable/ic_android_black_48dp"         android:checked="false"         android:title="Placeholder" /> </group> 

which adds a submenu which looks like this: enter image description here

However, I am unable to make this submenu look like this: (collapsable)

enter image description here

I now know that I need to implement an expandableListView, but I am not sure how this would fit in with the menu I have already created.

Any advice is appreciated

like image 667
mlz7 Avatar asked Sep 06 '15 02:09

mlz7


1 Answers

You can create it using custom ListView.

See the code below activity_navigation_view.xml

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout     android:id="@+id/drawer_layout"     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:fitsSystemWindows="true">      <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Hello World!" />      <android.support.design.widget.NavigationView         android:id="@+id/nav_view"         android:layout_width="wrap_content"         android:layout_height="match_parent"         android:layout_gravity="start"         android:fitsSystemWindows="true">          <ExpandableListView             android:id="@+id/navigationmenu"             android:layout_width="wrap_content"             android:layout_height="match_parent"             android:layout_marginTop="192dp"             android:background="@android:color/white">         </ExpandableListView>     </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> 

The adapter for expandable list view is as follows.

ExpandableListAdapter.java

import android.content.Context; import android.graphics.Typeface; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.TextView;  import java.util.HashMap; import java.util.List;  public class ExpandableListAdapter extends BaseExpandableListAdapter {     private Context mContext;     private List<ExpandedMenuModel> mListDataHeader; // header titles      // child data in format of header title, child title     private HashMap<ExpandedMenuModel, List<String>> mListDataChild;     ExpandableListView expandList;      public ExpandableListAdapter(Context context, List<ExpandedMenuModel> listDataHeader, HashMap<ExpandedMenuModel, List<String>> listChildData, ExpandableListView mView) {         this.mContext = context;         this.mListDataHeader = listDataHeader;         this.mListDataChild = listChildData;         this.expandList = mView;     }      @Override     public int getGroupCount() {         int i = mListDataHeader.size();         Log.d("GROUPCOUNT", String.valueOf(i));         return this.mListDataHeader.size();     }      @Override     public int getChildrenCount(int groupPosition) {         int childCount = 0;         if (groupPosition != 2) {             childCount = this.mListDataChild.get(this.mListDataHeader.get(groupPosition))                 .size();         }         return childCount;     }      @Override     public Object getGroup(int groupPosition) {         return this.mListDataHeader.get(groupPosition);     }      @Override     public Object getChild(int groupPosition, int childPosition) {         Log.d("CHILD", mListDataChild.get(this.mListDataHeader.get(groupPosition))             .get(childPosition).toString());         return this.mListDataChild.get(this.mListDataHeader.get(groupPosition))             .get(childPosition);     }      @Override     public long getGroupId(int groupPosition) {         return groupPosition;     }      @Override     public long getChildId(int groupPosition, int childPosition) {         return childPosition;     }      @Override     public boolean hasStableIds() {         return false;     }      @Override     public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {         ExpandedMenuModel headerTitle = (ExpandedMenuModel) getGroup(groupPosition);         if (convertView == null) {             LayoutInflater infalInflater = (LayoutInflater) this.mContext                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);             convertView = infalInflater.inflate(R.layout.listheader, null);         }         TextView lblListHeader = (TextView) convertView             .findViewById(R.id.submenu);         ImageView headerIcon = (ImageView) convertView.findViewById(R.id.iconimage);         lblListHeader.setTypeface(null, Typeface.BOLD);         lblListHeader.setText(headerTitle.getIconName());         headerIcon.setImageResource(headerTitle.getIconImg());         return convertView;     }      @Override     public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {         final String childText = (String) getChild(groupPosition, childPosition);          if (convertView == null) {             LayoutInflater infalInflater = (LayoutInflater) this.mContext                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);             convertView = infalInflater.inflate(R.layout.list_submenu, null);         }          TextView txtListChild = (TextView) convertView             .findViewById(R.id.submenu);          txtListChild.setText(childText);          return convertView;     }      @Override     public boolean isChildSelectable(int groupPosition, int childPosition) {         return true;     } } 

list_submenu.xml is as follows.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               android:layout_width="match_parent"               android:layout_height="match_parent"               android:orientation="vertical">      <TextView         android:id="@+id/submenu"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginLeft="20dp"         android:padding="10dp"         android:textColor="#000000"         android:textSize="18sp"/> </LinearLayout> 

listheader.xml is as follows.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               android:layout_width="match_parent"               android:layout_height="2dp"               android:orientation="vertical">      <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         android:layout_marginLeft="20dp"         android:orientation="horizontal">          <ImageView             android:id="@+id/iconimage"             android:layout_width="50dp"             android:layout_height="50dp"             android:paddingBottom="10dp"             android:paddingLeft="10dp"             android:paddingTop="10dp"/>          <TextView             android:id="@+id/submenu"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:padding="10dp"             android:textColor="#000000"             android:textSize="20sp"/>      </LinearLayout>  </LinearLayout> 

In your navigation view activity, set the adapter for the expandable list view. NavigationViewActivity.java

public class NavigationViewActivity extends AppCompatActivity {      private DrawerLayout mDrawerLayout;     ExpandableListAdapter mMenuAdapter;     ExpandableListView expandableList;     List<ExpandedMenuModel> listDataHeader;     HashMap<ExpandedMenuModel, List<String>> listDataChild;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_navigation_view);         final ActionBar ab = getSupportActionBar();         /* to set the menu icon image*/         ab.setHomeAsUpIndicator(android.R.drawable.ic_menu_add);         ab.setDisplayHomeAsUpEnabled(true);         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);         expandableList = (ExpandableListView) findViewById(R.id.navigationmenu);         NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);          if (navigationView != null) {             setupDrawerContent(navigationView);         }          prepareListData();         mMenuAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild, expandableList);          // setting list adapter         expandableList.setAdapter(mMenuAdapter);          expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {             @Override             public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {                 //Log.d("DEBUG", "submenu item clicked");                 return false;             }         });         expandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {             @Override             public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {                 //Log.d("DEBUG", "heading clicked");                 return false;             }         });     }      private void prepareListData() {         listDataHeader = new ArrayList<ExpandedMenuModel>();         listDataChild = new HashMap<ExpandedMenuModel, List<String>>();          ExpandedMenuModel item1 = new ExpandedMenuModel();         item1.setIconName("heading1");         item1.setIconImg(android.R.drawable.ic_delete);         // Adding data header         listDataHeader.add(item1);          ExpandedMenuModel item2 = new ExpandedMenuModel();         item2.setIconName("heading2");         item2.setIconImg(android.R.drawable.ic_delete);         listDataHeader.add(item2);          ExpandedMenuModel item3 = new ExpandedMenuModel();         item3.setIconName("heading3");         item3.setIconImg(android.R.drawable.ic_delete);         listDataHeader.add(item3);          // Adding child data         List<String> heading1 = new ArrayList<String>();         heading1.add("Submenu of item 1");          List<String> heading2 = new ArrayList<String>();         heading2.add("Submenu of item 2");         heading2.add("Submenu of item 2");         heading2.add("Submenu of item 2");          listDataChild.put(listDataHeader.get(0), heading1);// Header, Child data         listDataChild.put(listDataHeader.get(1), heading2);      }      @Override     public boolean onCreateOptionsMenu(Menu menu) {         return true;     }      @Override     public boolean onOptionsItemSelected(MenuItem item) {         switch (item.getItemId()) {             case android.R.id.home:                 mDrawerLayout.openDrawer(GravityCompat.START);                 return true;         }         return super.onOptionsItemSelected(item);     }      private void setupDrawerContent(NavigationView navigationView) {         //revision: this don't works, use setOnChildClickListener() and setOnGroupClickListener() above instead         navigationView.setNavigationItemSelectedListener(             new NavigationView.OnNavigationItemSelectedListener() {                 @Override                 public boolean onNavigationItemSelected(MenuItem menuItem) {                     menuItem.setChecked(true);                     mDrawerLayout.closeDrawers();                     return true;                 }             });     }  } 

ExpandedMenuModel class contains menu item details as follow.

ExpandedMenuModel.java

public class ExpandedMenuModel {      String iconName = "";     int iconImg = -1; // menu icon resource id      public String getIconName() {         return iconName;     }     public void setIconName(String iconName) {         this.iconName = iconName;     }     public int getIconImg() {         return iconImg;     }     public void setIconImg(int iconImg) {         this.iconImg = iconImg;     }  } 

[Side note]:

  1. Don't put import android.widget.ExpandableListAdapter; in NavigationViewActivity.java. This mistake can happen if you resolve import by Alt+Enter before create the file ExpandableListAdapter.java.

  2. Put compile 'com.android.support:design:23.3.0' in app's build.gradle, it's for "NavigationView" and its "import android.support.design.widget.NavigationView;" After that (Might require rebuild first) you can do Alt-Enter to resolve import.

The file hierarchy should look like (3 .java and 3 .xml from above):

enter image description here

The output screenshot:

enter image description here

like image 88
Priyank Patel Avatar answered Oct 19 '22 16:10

Priyank Patel