【问题标题】:Android Navigation Drawer ExpandableListViewAndroid 导航抽屉 ExpandableListView
【发布时间】:2017-08-01 04:16:04
【问题描述】:

我正在尝试在导航抽屉菜单下实现子菜单。将只有一组菜单。看下图我想要做什么。目前我只从 xml 菜单列表中添加了主菜单。如何将ExpandableListView作为SubMenu添加到Menu中,得到如下类型的界面。

这是我用来打开/关闭导航抽屉并在抽屉菜单单击时启动活动的代码

navigationView = (NavigationView) findViewById(R.id.navigation_view);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);

//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {

                Intent intent;
                int id = item.getItemId();

                //Check to see which item was being clicked and perform appropriate action
                if (id == R.id.favorites) {
                    Intent favoritesIntent = new Intent(MainActivity.this, Favorites.class);
                    startActivity(favoritesIntent);
                } else if (id == R.id.settings) {
                    Intent settingsIntent = new Intent(MainActivity.this, Settings.class);
                    startActivity(settingsIntent);
                }

                drawerLayout.closeDrawer(GravityCompat.START);
                return true;

            }
        });

        // Initializing Drawer Layout and ActionBarToggle
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

                super.onDrawerOpened(drawerView);
            }
        };

        actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
        ImageView titleLogo = (ImageView) findViewById(R.id.titleLogo);
        titleLogo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                drawerLayout.openDrawer(GravityCompat.START);

            }


      });
    .....

        @Override
            public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }

这是我使用的 XML

<android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        app:itemTextColor="@color/white"
        app:itemIconTint="@color/white"
        app:headerLayout="@layout/header"
        app:menu="@menu/drawer"
        android:background="@color/colorPrimary" >

    </android.support.design.widget.NavigationView>

这里是菜单列表的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/favorites"
            android:checked="false"
            android:icon="@drawable/favorites"
            android:title="@string/favorites" />

        <item
            android:id="@+id/services"
            android:checked="false"
            android:icon="@drawable/services"
            android:title="@string/services" />

        <item
            android:id="@+id/settings"
            android:checked="false"
            android:icon="@drawable/settings"
            android:title="@string/settings" />

    </group>
</menu>

【问题讨论】:

    标签: android navigation-drawer expandablelistview


    【解决方案1】:

    如果您想为 NavigationDrawer 实现上述行为,您可以按照以下步骤操作:

    1) 您必须将 Expandable listview 添加到 NavigationView。

    2) 创建标题视图

    3) 创建子视图。

    4) 扩展 BaseExpandableListAdapter

    5) 在 MainActivity 中设置适配器

    可用的解决方案很少。您可以关注this 教程或this。有关创建导航抽屉的基本知识,您可以去here。我得到了这些教程的帮助,而且它们很容易应用。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      从这里下载源代码 (Navigation drawer with expandablelistview in android)

      MainActivity.java

      package com.deepshikha.navigationdrawer;
      
      import android.support.v4.widget.DrawerLayout;
      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.Gravity;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.ExpandableListAdapter;
      import android.widget.ExpandableListView;
      import android.widget.RelativeLayout;
      import android.widget.TextView;
      
      import org.json.JSONArray;
      import org.json.JSONException;
      import org.json.JSONObject;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.ArrayList;
      
      public class MainActivity extends AppCompatActivity {
      
          ArrayList<Model_country> al_main = new ArrayList<>();
          ExpandableListView ev_list;
          CountryAdapter obj_adapter;
          String TAG = "MainActivity";
          private DrawerLayout mDrawerLayout;
          HomeFragment fragment;
          TextView tv_name;
          RelativeLayout rl_menu;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              fn_data();
              init();
      
          }
      
          private void init() {
      
              getSupportActionBar().hide();
              ev_list = (ExpandableListView) findViewById(R.id.ev_menu);
              tv_name = (TextView) findViewById(R.id.tv_name);
              rl_menu = (RelativeLayout) findViewById(R.id.rl_menu);
              mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
              obj_adapter = new CountryAdapter(MainActivity.this, al_main);
              ev_list.setAdapter(obj_adapter);
              ev_list.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
      
                  @Override
                  public boolean onGroupClick(ExpandableListView parent, View v,
                                              int groupPosition, long id) {
                      setListViewHeight(parent, groupPosition);
                      return false;
                  }
              });
      
              setExpandableListViewHeightBasedOnChildren(ev_list);
      
              fragment = new HomeFragment();
              Bundle bundle = new Bundle();
              bundle.putString("name", al_main.get(0).getStr_country());
              bundle.putString("des", al_main.get(0).getAl_state().get(0).getStr_description());
              bundle.putString("dish", al_main.get(0).getAl_state().get(0).getStr_name());
              bundle.putString("image", al_main.get(0).getAl_state().get(0).getStr_image());
              tv_name.setText(al_main.get(0).getStr_country());
      
              fragment.setArguments(bundle);
              getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, "HomeFragment").addToBackStack("null").commit();
      
      
              rl_menu.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      mDrawerLayout.openDrawer(Gravity.LEFT);
                  }
              });
          }
      
          private void setListViewHeight(ExpandableListView listView, int group) {
              ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
              int totalHeight = 0;
              int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                      View.MeasureSpec.EXACTLY);
              for (int i = 0; i < listAdapter.getGroupCount(); i++) {
                  View groupItem = listAdapter.getGroupView(i, false, null, listView);
                  groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
      
                  totalHeight += groupItem.getMeasuredHeight();
      
                  if (((listView.isGroupExpanded(i)) && (i != group))
                          || ((!listView.isGroupExpanded(i)) && (i == group))) {
                      for (int j = 0; j < listAdapter.getChildrenCount(i); j++) {
                          View listItem = listAdapter.getChildView(i, j, false, null,
                                  listView);
                          listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
      
                          totalHeight += listItem.getMeasuredHeight();
      
                      }
                  }
              }
      
              ViewGroup.LayoutParams params = listView.getLayoutParams();
              int height = totalHeight
                      + (listView.getDividerHeight() * (listAdapter.getGroupCount() - 1));
             /* if (height < 10)
                  height = 200;*/
              params.height = height;
              listView.setLayoutParams(params);
              listView.requestLayout();
      
          }
      
          private void fn_data() {
      
              String str_data = loadJSONFromAsset();
      
              try {
                  JSONObject jsonObject_country = new JSONObject(str_data);
                  JSONArray jsonArray_country = jsonObject_country.getJSONArray("country");
                  al_main = new ArrayList<>();
                  for (int i = 0; i < jsonArray_country.length(); i++) {
                      Model_country obj_country = new Model_country();
                      JSONObject jsonObject = jsonArray_country.getJSONObject(i);
                      JSONArray jsonArray_dishes = jsonObject.getJSONArray("dishes");
                      ArrayList<Model_Dish> al_dishes = new ArrayList<>();
                      for (int j = 0; j < jsonArray_dishes.length(); j++) {
      
                          JSONObject jsonObject_dishes = jsonArray_dishes.getJSONObject(j);
                          Model_Dish obj_dish = new Model_Dish();
                          obj_dish.setStr_name(jsonObject_dishes.getString("dishname"));
                          obj_dish.setStr_description(jsonObject_dishes.getString("description"));
                          obj_dish.setStr_image(jsonObject_dishes.getString("image"));
                          al_dishes.add(obj_dish);
                      }
      
                      obj_country.setAl_state(al_dishes);
                      obj_country.setStr_country(jsonObject.getString("name"));
      
                      al_main.add(obj_country);
                  }
              } catch (JSONException e) {
                  e.printStackTrace();
              }
      
          }
      
          public static void setExpandableListViewHeightBasedOnChildren(ExpandableListView expandableListView) {
              CountryAdapter adapter = (CountryAdapter) expandableListView.getExpandableListAdapter();
              if (adapter == null) {
                  return;
              }
              int totalHeight = expandableListView.getPaddingTop() + expandableListView.getPaddingBottom();
              for (int i = 0; i < adapter.getGroupCount(); i++) {
                  View groupItem = adapter.getGroupView(i, false, null, expandableListView);
                  groupItem.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
                  totalHeight += groupItem.getMeasuredHeight();
      
                  if (expandableListView.isGroupExpanded(i)) {
                      for (int j = 0; j < adapter.getChildrenCount(i); j++) {
                          View listItem = adapter.getChildView(i, j, false, null, expandableListView);
                          listItem.setLayoutParams(new ViewGroup.LayoutParams(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED));
                          listItem.measure(View.MeasureSpec.makeMeasureSpec(0,
                                  View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
                                  .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                          totalHeight += listItem.getMeasuredHeight();
      
                      }
                  }
              }
      
              ViewGroup.LayoutParams params = expandableListView.getLayoutParams();
              int height = totalHeight + expandableListView.getDividerHeight() * (adapter.getGroupCount() - 1);
      
              if (height < 10)
                  height = 100;
              params.height = height;
              expandableListView.setLayoutParams(params);
              expandableListView.requestLayout();
          }
      
          public String loadJSONFromAsset() {
              String json = null;
              try {
      
                  InputStream is = getAssets().open("dishes.json");
      
                  int size = is.available();
      
                  byte[] buffer = new byte[size];
      
                  is.read(buffer);
      
                  is.close();
      
                  json = new String(buffer, "UTF-8");
      
      
              } catch (IOException ex) {
                  ex.printStackTrace();
                  return null;
              }
      
              Log.e(TAG, "Json response " + json);
              return json;
      
          }
      
          public void fn_selectedPosition(int group, int child) {
      
              fragment = new HomeFragment();
              Bundle bundle = new Bundle();
              bundle.putString("name", al_main.get(group).getStr_country());
              bundle.putString("des", al_main.get(group).getAl_state().get(child).getStr_description());
              bundle.putString("dish", al_main.get(group).getAl_state().get(child).getStr_name());
              bundle.putString("image", al_main.get(group).getAl_state().get(child).getStr_image());
              fragment.setArguments(bundle);
      
              getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, "HomeFragment").addToBackStack("null").commit();
              mDrawerLayout.closeDrawer(Gravity.LEFT);
      
              tv_name.setText(al_main.get(group).getStr_country());
          }
      
          @Override
          public void onBackPressed() {
              super.onBackPressed();
              finish();
          }
      }
      

      CountryAdapter.java

      package com.deepshikha.navigationdrawer;
      
      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;
      
      /**
       * Created by deepshikha on 12/7/17.
       */
      
      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;
          }
      
      
      }
      

      谢谢!

      【讨论】:

        【解决方案3】:

        无法将可扩展列表视图与 android 内置抽屉菜单集成。 因此您可以对整个抽屉菜单使用可扩展的列表视图,而不是使用 menu.xml 文件。但是您可以做的一个技巧是在每个组展开时计算它的高度并在运行时设置高度。 因此,假设您遵循@tahsinRupam 的所有步骤,您需要在运行时计算如下高度:

        expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
                    @Override
                    public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
        
                        if (expandableListView.isGroupExpanded(i)){
                            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                            expandableListView.setLayoutParams(params);
                        } else {
                            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 130 + any_number_of_child_items_you_have * 87);
                            expandableListView.setLayoutParams(params);
                        }
        
                        return false;
                    }
                });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多