点击导航抽屉菜单项后如何打开子菜单?

13
我实现了一个导航抽屉,使用导航视图,并通过menu.xml文件向导航视图添加值。
<android.support.design.widget.NavigationView
android:id="@+id/nvView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemTextColor="@android:color/white"
android:background="?attr/colorAccent"
app:menu="@menu/drawer_view"
app:headerLayout="@layout/nav_header"
>
</android.support.design.widget.NavigationView>

每件事情都运行正常,但是我遇到了一个问题,我想在菜单上单击后显示子菜单。
我尝试了很多方法,例如:在menu.xml中添加子菜单,就像这样的项目。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">

<item
    android:id="@+id/nav_ChangeOutlet_fragment"
    android:icon="@drawable/home_icon"
    android:title="@string/changeOutlet"
    android:checked="true">
    <menu>
        <group>
            <item
                android:title="one"></item>
            <item
                android:title="two"></item>
            <item
                android:title="three"></item>

        </group>
    </menu>

然后它会返回这样的输出给我。
输出:点击此链接查看输出。

https://drive.google.com/file/d/0B0B9-WZYydK7RG1yY0tRdkhOSW8/view?usp=sharing

现在的问题是,我无法点击菜单,只能点击子菜单。 我希望只有在点击菜单后才显示子菜单,否则子菜单将对其他人不可见。请注意保留HTML标签。

你可以将图片上传到像Dropbox或Google Drive这样的地方,然后分享链接。 - Bunny
这是一段不完整的代码,请参考链接:https://dev59.com/tFwY5IYBdhLWcg3wnY13 - Rishabh Saxena
不完整的解决方案,请参考链接:https://dev59.com/tFwY5IYBdhLWcg3wnY13 - Rishabh Saxena
3个回答

27
最佳解决方案是在导航视图中使用可扩展的列表视图。请参见下面的代码activity_navigation_view.xml。
     <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_height="match_parent"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true">    
    <include layout="@layout/navigation_view_fragment_container"/>
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/navigation_view_header">
    <ExpandableListView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:layout_marginTop="192dp"
        android:id="@+id/navigationmenu">
   </ExpandableListView>
   </android.support.design.widget.NavigationView>
   </android.support.v4.widget.DrawerLayout>

布局导航头如下所示 navigation_view_header.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="192dp"
       android:background="#ff5722"
       android:padding="16dp"
       android:theme="@style/ThemeOverlay.AppCompat.Dark"
       android:orientation="vertical"
       android:gravity="bottom">
  <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Username"
      android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
  </LinearLayout>

在你的导航视图活动中,为可扩展列表视图设置适配器。 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(R.drawable.ic_menu);
    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);
   }

    private void prepareListData() {
    listDataHeader = new ArrayList<String>();
    listDataChild = new HashMap<String, List<String>>();

    // Adding data header
    listDataHeader.add("heading1");
    listDataHeader.add("heading2");
    listDataHeader.add("heading3");

    // 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) {
    getMenuInflater().inflate(R.menu.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) {
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    menuItem.setChecked(true);
                    mDrawerLayout.closeDrawers();
                    return true;
                }
            });
}


@Override
public void onFragmentInteraction(Boolean isDataSaved) {

}
}
适用于可扩展列表视图的适配器如下:

可扩展列表视图的适配器如下所示。

   public class ExpandableListAdapter extends BaseExpandableListAdapter {
       private Context mContext;
       private List<String> mListDataHeader; // header titles

       // child data in format of header title, child title
       private HashMap<String, List<String>> mListDataChild;
       ExpandableListView  expandList;
   public ExpandableListAdapter(Context context, List<String> listDataHeader,HashMap<String, 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.setImageDrawable(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如下所示:

    <?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">
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:padding="10dp"
      android:textColor="#000000"
      android:layout_marginLeft="20dp"
      android:textSize="18sp"
      android:id="@+id/submenu"/>
  </LinearLayout>

listheader.xml 的内容如下:

    <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
     android:layout_width="match_parent"
     android:layout_height="2dp"
     android:orientation="vertical"
     xmlns:android="http://schemas.android.com/apk/res/android" >

 <LinearLayout
     android:layout_width="match_parent"
     android:layout_height="match_parent">
<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:paddingBottom="10dp"
    android:paddingLeft="10dp"
    android:paddingTop="10dp"
    android:id="@+id/iconimage"/>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textColor="#000000"
    android:textSize="20sp"
    android:id="@+id/submenu"/>
</LinearLayout>

</LinearLayout>

我已经发布了整个代码以便更加清晰。希望这可以帮助到您......


2
谢谢您已经发布了所有的代码。如果您能够发布ExpandedMenuModel类,那将非常有帮助。 - Prashanth Debbadwar
1
这个答案是从 https://dev59.com/tFwY5IYBdhLWcg3wnY13#32664433 复制的。上面的答案不完整,缺少一些类,比如ExpandedMenuModel,即使在activity中也存在冲突,因为list被定义为List<ExpandedMenuModel> listDataHeader; 但是却被用作listDataHeader = new ArrayList<String>();。 - Kourosh Arian

10

您可以使用可扩展列表视图(ExpandableListView)来创建它。

看这个:here


1

我建议您在侧边导航抽屉中使用自定义布局。

这里是一个示例链接 - 如何在导航抽屉中实现自定义布局。

您还需要在侧边导航抽屉中实现可扩展的列表视图,这里 是可扩展列表视图的示例。

您需要将两者结合起来,以实现具有可扩展列表的导航抽屉。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接