默认导航抽屉视图到ExpandableListView

在Android Studio 2.1.2中,如果我创build一个默认的导航活动,我得到这个视图:

在这里输入图像说明

其中使用以下activity_main.xml文件:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <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" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout> 

正如你可以看到<android.support.design.widget.NavigationView/>使用app:menu="@menu/activity_main_drawer"来显示在activity_main_drawer.xml文件中定义的菜单列表,如下所示:

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <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" android:icon="@drawable/ic_menu_gallery" android:title="Gallery" /> <item android:id="@+id/nav_slideshow" 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> <item android:title="Communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="Share" /> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="Send" /> </menu> </item> </menu> 

现在我的计划是replace在activity_main_drawer.xml中定义的菜单列表,而是使用ExpandableListView 。 因为我想要我的菜单项有子类别,例如,菜单项目Cars将有DieselPetrolHybrid等子类我已经做了研究,似乎没有人有我需要的确切的工作解决scheme。

我看了这里:

  1. 开放教程
  2. 在android studio的导航抽屉活动中实现expandablelistview
  3. Android:导航抽屉里有2个或更多的ExpandableListView
  4. 如何在导航抽屉里创build一个可展开的listView?

和那里提到的后续链接。

注意:上面的链接提到在导航抽屉中使用ListView ,而Android Studio通过使用activity_main_drawer.xml使用menu项来实现这一点。

有人能给我提供一个这样的工作例子吗? 要重新迭代,我想要在默认导航抽屉活动内部展开的列表视图。 我收集到,我将需要XML文件和Java类代码,让我的基础,我需要开始。

提前致谢。 🙂

编辑:最后看样机(对不起我的photoshop技能) 在这里输入图像说明

我目前的做法是创build一个新的布局ex_list如下:

 <?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="match_parent"> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <ExpandableListView android:id="@+id/lvExp" android:layout_height="match_parent" android:layout_width="match_parent"/> </android.support.v4.widget.DrawerLayout> </LinearLayout> 

并编辑activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="240dp" android:layout_gravity = "start" android:layout_height="match_parent" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main"> <include layout="@layout/ex_list" android:layout_height="wrap_content" android:layout_width="match_parent"/> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> 

其结果如下布局:

在这里输入图像说明

和错误信息

  java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY. at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1036) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at android.support.design.widget.NavigationView.onMeasure(NavigationView.java:223) at android.view.View.measure(View.java:18788) at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1104) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643) at android.view.View.measure(View.java:18788) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:606) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

我究竟做错了什么?

回答:

在这里输入图像说明

谢谢@Moulesh!

Solutions Collecting From Web of "默认导航抽屉视图到ExpandableListView"

这是可扩展列表适配器的代码:

 public class ExpandListAdapter extends BaseExpandableListAdapter { private Context _context; private List<String> _listDataHeader; // header titles // child data in format of header title, child title private HashMap<String, List<String>> _listDataChild; public ExpandListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listChildData) { this._context = context; this._listDataHeader = listDataHeader; this._listDataChild = listChildData; } @Override public Object getChild(int groupPosition, int childPosititon) { return this._listDataChild.get(this._listDataHeader.get(groupPosition)) .get(childPosititon); } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { final String childText = (String) getChild(groupPosition, childPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) this._context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.list_item, null); } TextView txtListChild = (TextView) convertView .findViewById(R.id.lblListItem); txtListChild.setText(childText); return convertView; } @Override public int getChildrenCount(int groupPosition) { return this._listDataChild.get(this._listDataHeader.get(groupPosition)) .size(); } @Override public Object getGroup(int groupPosition) { return this._listDataHeader.get(groupPosition); } @Override public int getGroupCount() { return this._listDataHeader.size(); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { String headerTitle = (String) getGroup(groupPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) this._context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.list_group, null); } TextView lblListHeader = (TextView) convertView .findViewById(R.id.lblListHeader); lblListHeader.setTypeface(null, Typeface.BOLD); lblListHeader.setText(headerTitle); return convertView; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; }} 

在你的活动中:

  private void enableExpandableList() { listDataHeader = new ArrayList<String>(); listDataChild = new HashMap<String, List<String>>(); expListView = (ExpandableListView) findViewById(R.id.left_drawer); prepareListData(listDataHeader, listDataChild); listAdapter = new ExpandListAdapter(this, listDataHeader, listDataChild); // setting list adapter expListView.setAdapter(listAdapter); expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { // Toast.makeText(getApplicationContext(), // "Group Clicked " + listDataHeader.get(groupPosition), // Toast.LENGTH_SHORT).show(); return false; } }); // Listview Group expanded listener expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { Toast.makeText(getApplicationContext(), listDataHeader.get(groupPosition) + " Expanded", Toast.LENGTH_SHORT).show(); } }); // Listview Group collasped listener expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { Toast.makeText(getApplicationContext(), listDataHeader.get(groupPosition) + " Collapsed", Toast.LENGTH_SHORT).show(); } }); // Listview on child click listener expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { // TODO Auto-generated method stub // Temporary code: // till here Toast.makeText( getApplicationContext(), listDataHeader.get(groupPosition) + " : " + listDataChild.get( listDataHeader.get(groupPosition)).get( childPosition), Toast.LENGTH_SHORT) .show(); return false; } });} 

用数据创build列表的方法:

  private void prepareListData(List<String> listDataHeader, Map<String, List<String>> listDataChild) { // Adding child data listDataHeader.add("Product1"); listDataHeader.add("product2"); listDataHeader.add("Product3"); // Adding child data List<String> top = new ArrayList<String>(); top.add("x1"); top.add("x2"); top.add("x3"); top.add("x4"); top.add("x5"); List<String> mid = new ArrayList<String>(); mid.add("y1"); mid.add("y2"); mid.add("y3"); List<String> bottom = new ArrayList<String>(); bottom.add("z1"); bottom.add("z2"); bottom.add("z3"); listDataChild.put(listDataHeader.get(0), top); // Header, Child data listDataChild.put(listDataHeader.get(1), mid); listDataChild.put(listDataHeader.get(2), bottom); } 

这个代码在布局xml中

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include android:id="@+id/act_bar" layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <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" app:headerLayout="@layout/nav_header_main"> <!--app:menu="@menu/activity_main_drawer"--> <ExpandableListView android:id="@+id/left_drawer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/nav_header_height" android:background="@color/Background" android:dividerHeight="0dp" /> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> 

xml为ExplistHeader list_group.xml

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingTop="10dp" android:padding="30dp" android:background="@color/Background"> <TextView android:id="@+id/lblListHeader" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="? android:attr/expandableListPreferredItemPaddingLeft" android:textSize="17dp" android:textColor="@color/colorTextPrimary" /> </LinearLayout> 

xml for Explistchild list_item.xml

  <?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="55dip" android:background="@color/Background" android:orientation="vertical" > <TextView android:id="@+id/lblListItem" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="17dip" android:paddingTop="5dp" android:paddingBottom="5dp" android:paddingLeft="? android:attr/expandableListPreferredChildPaddingLeft" /> </LinearLayout> 

从这里下载源代码( 在android中使用expandablelistview导航抽屉 )

  import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.TextView; import java.util.ArrayList; public class CountryAdapter extends BaseExpandableListAdapter { Context context; ArrayList<Model_country> al_country; public CountryAdapter(Context context, ArrayList<Model_country> al_country) { this.context = context; this.al_country = al_country; } @Override public int getGroupCount() { return al_country.size(); } @Override public int getChildrenCount(int i) { return al_country.get(i).getAl_state().size(); } @Override public Object getGroup(int i) { return al_country.get(i); } @Override public Object getChild(int i, int i1) { return al_country.get(i).getAl_state().get(i1); } @Override public long getGroupId(int i) { return i; } @Override public long getChildId(int i, int i1) { return i1; } @Override public boolean hasStableIds() { return false; } @Override public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) { if (view==null){ LayoutInflater layoutInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = layoutInflater.inflate(R.layout.adapter_header, null); } TextView tv_state = (TextView)view.findViewById(R.id.tv_name); tv_state.setText(al_country.get(i).getStr_country()); return view; } @Override public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) { if (view==null){ LayoutInflater layoutInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = layoutInflater.inflate(R.layout.adapter_childview, null); } TextView tv_state = (TextView)view.findViewById(R.id.tv_name); tv_state.setText(al_country.get(i).getAl_state().get(i1).getStr_name()); tv_state.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ((MainActivity)context).fn_selectedPosition(i,i1); } }); return view; } @Override public boolean isChildSelectable(int i, int i1) { return false; } } 

谢谢!

 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/DrawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:elevation="7dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include android:id="@+id/tool_bar" layout="@layout/toolbar"></include> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent"></FrameLayout> </LinearLayout> <ExpandableListView android:id="@+id/left_drawer" android:layout_width="250dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/colorPrimary" android:childDivider="@color/green" android:choiceMode="singleChoice" />