安卓导航抽屉可扩展列表视图

8
我正在尝试在导航抽屉菜单下实现子菜单。只会有一个组菜单。请看下面的图像,我想要做什么。目前,我只添加了来自xml菜单列表的主菜单。如何将可展开列表视图添加到菜单作为子菜单,以获取以下类型的接口。

enter image description here

这里是我用于打开/关闭导航抽屉和在抽屉菜单单击上启动活动的代码

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>
3个回答

8
如果您想要将上述功能应用于您的NavigationDrawer,可以按照以下步骤进行操作:
1)向NavigationView添加可扩展列表视图。
2)创建标题视图。
3)创建子视图。
4)扩展BaseExpandableListAdapter。
5)在MainActivity中设置适配器。
有几种解决方案可供选择。您可以参考教程或链接。如需了解创建导航抽屉的基本知识,请访问此处。我通过这些教程得到了帮助,并且它们非常易于应用。
希望这能帮到您。

2

从这里下载源代码 (在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;
    }


}

谢谢!


0

无法将可扩展列表视图与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;
            }
        });

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