侧滑菜单DrawerLayout+ExpandableListView的实现

最近需要使用到这样一个功能:实现侧滑菜单,且滑动菜单使用到ExpandableListView这样的抽屉控件,虽然大致知道是怎么实现的,但是一具体来操作还是出现诸多问题。也是给了自己不小的打击和警示。SO,纸上得来终觉浅,绝知此事要躬行。此后一定要告诫自己,要适当的进行深度挖掘理解,抓牢每一个知识点。

ExpandableListView

ExpandableListView组件类似抽屉一样,它的使用就非常简单了。那么先简单看下ExpandableListView将会用到些什么东西:父栏目与子栏目的Item布局、父栏目与子栏目的数据、baseExpandableListViewAdapter的使用,以及实现子栏目监听ChildClickListener。

1.1、父栏目与子栏目的布局:为了简单演示,这里只是想让父栏目与子栏目显示文字

<?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/parent_TV"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"/>

</LinearLayout>

1.2、定义好布局之后,就需要考虑我们父栏目与子栏目需要怎样的数据,为了简单演示,直接定义需要的数据。

    private void initData() {

        //父栏目中的数据
        parent = new ArrayList<String>();
        parent.add("one");
        parent.add("two");
        //为每个父栏目添加子栏目元素
        map = new HashMap<String ,List<String>>();
        List<String> list_1 = new ArrayList<String>();
        list_1.add("one_1");
        list_1.add("one_2");
        map.put("one", list_1);
        List<String> list_2 = new ArrayList<String>();
        list_2.add("two_1");
        list_2.add("two_2");
        map.put("two", list_2);

    }

1.3、实现baseExpandableListViewAdapter适配器,尤其是getGroupView与getChildView这两个方法。

class MyAdapter extends BaseExpandableListAdapter{

        @Override
        public int getGroupCount() {
            return parent.size();
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            String key = parent.get(groupPosition);
            int size = map.get(key).size();
            return size;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return parent.get(groupPosition);
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            String key = parent.get(groupPosition);
            return map.get(key).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 true;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) MainActivity.this
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.parent_layout, null);
            }
            TextView tv = (TextView) convertView
                    .findViewById(R.id.parent_TV);
            tv.setText(MainActivity.this.parent.get(groupPosition));
            return tv;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView == null){
                LayoutInflater inflater = MainActivity.this.getLayoutInflater();
                convertView = inflater.inflate(R.layout.children_layout, null);
            }
            TextView tv = (TextView) convertView.findViewById(R.id.children_TV);
            String key = MainActivity.this.parent.get(groupPosition);
            String info = map.get(key).get(childPosition);
            tv.setText(info);
            return tv;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

    }

1.4、如果要想为子栏目实现监听

mListView.setOnChildClickListener(new OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {
                String key = MainActivity.this.parent.get(groupPosition);
                if (map.get(key).get(childPosition).equals("one_1")){

                }
                return false;
            }
        });

最后,ExpandableListView的使用大致就是这样。接下来需要了解DrawerLayout的使用。

DrawerLayout

惯例,先回顾下DrawerLayout思路:首先是引入布局,然后若有必要需实现监听(DrawerListener(需实现全部方法) or SimpleDrawerListener),他们内容的替换会使用的Fragment,而Fragment强调FragmentManager、Translation、commit。

2.1、DrawerLayout是继承与ViewGroup的,直接当做布局来使用,需要在xml文件中引用此布局,(注意是在android.support.v4.widget.DrawerLayout包下的)如:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--内容区域  -->
    <FrameLayout 
        android:id="@+id/drawer_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ff00ff"/>

    <!-- 因为layout_gravity指定的为start,所以会在左侧出现菜单 -->
    <!-- 此处既可以使用start,也可以使用left,效果完全不变,出现这样的情况是文化差异 -->
    <ExpandableListView
        android:id="@+id/drawer_elv"
        android:layout_width="140dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#00ff00"/>

    <!-- 右侧菜单 -->
    <ListView 
        android:layout_width="140dp"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:background="#00ff00"/>

</android.support.v4.widget.DrawerLayout>

2.1、监听

mDrawerLayout.setDrawerListener(new DrawerListener() {
            @Override
            public void onDrawerStateChanged(int arg0) {
//              Toast.makeText(MainActivity_1.this, "Changed", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDrawerSlide(View arg0, float arg1) {
//              Toast.makeText(MainActivity_1.this, "Slide", Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onDrawerOpened(View arg0) {
//              Toast.makeText(MainActivity_1.this, "Opened", Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onDrawerClosed(View arg0) {
//              Toast.makeText(MainActivity_1.this, "Closed", Toast.LENGTH_SHORT).show();

            }
        });

2.3、Fragment

manager.beginTransaction().replace(R.id.drawer_content, f2).commit();

到此,DrawerLayout就是如此简单。结合起来只需要替换ListView而已。通过查询官方的API可知道,官方将DrawerLayout的使用归入Implenenting Effective Navigation。???什么意思呢?实现有效导航?字面意思是这样就暂且理解为实现有效导航吧。接下来将要看看实现有效导航中有哪些未知的东东呢?
这里写图片描述
1、Creating Swipe Views with Tabs (其实就是ViewPager的使用)。

2、Creating a Navigation Drawer。此节以了解

3、Providing up Navigation。提供向上导航?英语做鸡呀。

4、Providing Proper Back Navigation。提供适当的后退导航?

5、Implementing Descendant Navigation。实现后裔导航?哈哈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用ExpandableListView可以实现QQ好友分组列表。首先需要创建一个ExpandableListView控件,并为其设置适配器。适配器需要继承BaseExpandableListAdapter,并实现以下方法: 1. getGroupCount():获取分组的数量。 2. getChildrenCount():获取某个分组下子项的数量。 3. getGroup():获取某个分组的数据。 4. getChild():获取某个分组下某个子项的数据。 5. getGroupId():获取某个分组的ID。 6. getChildId():获取某个分组下某个子项的ID。 7. hasStableIds():判断分组和子项的ID是否稳定。 8. getGroupView():获取分组的视图。 9. getChildView():获取子项的视图。 10. isChildSelectable():判断子项是否可选中。 在实现适配器的过程中,需要根据数据源的结构来设置分组和子项的数据。例如,可以使用一个List<List<String>>来存储分组和子项的数据,其中外层List表示分组,内层List表示子项。在getGroup()和getChild()方法中,需要根据groupPosition和childPosition来获取对应的数据。 最后,需要为ExpandableListView设置分组的展开和收起事件。可以通过设置OnGroupClickListener和OnChildClickListener来实现。在OnGroupClickListener中,需要根据groupPosition来判断当前分组是否已经展开,如果已经展开则返回false,否则返回true。在OnChildClickListener中,可以根据childPosition来获取对应的数据,并进行相应的操作。 通过以上步骤,就可以实现一个简单的QQ好友分组列表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值