Android开发丶ExpandableListView嵌套GridView的实现

开发过程中有个需求,要做出一个折叠列表布局,每个列表条目下还有可以三图一行的列表,分析界面后,发现这个可以用现有的控件ExpanadableListView和GridView组合嵌套来实现,即ExpandableListView来战展示标题数据,gridview来展示内部图片,照着这个思路,很快就实现出来了,这里做一下整理归纳。              

我们先看一下实际效果

没展开前,初始状态,

点击,展开。


下面谈谈实现流程

1.首先在主界面XML文件里放一个ExpandableListView,这里因为我们要自己加入箭头符号,所以将background设为

   null。

    <ExpandableListView
        android:id="@+id/main_elv"
        android:layout_width="match_parent"
        android:groupIndicator="@null"
        android:dividerHeight="1px"
        android:divider="#26000000"
        android:layout_height="match_parent"/>

2.这里我们先撸一个继承于GridView的自定义gridview来适应ExpandableListView,否则嵌套后GrdiView会出现不能滑动的bug。                       

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>> 2,  MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}      

3.我们来画一级列表item_group的xml布局。


没什么复杂的东西,就是个ImageView和TextView,注意好间距,字体大小之类的就可以。

item_group.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="wrap_content"
    android:padding="15dp"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/group_arrow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_group_open_normal"/>

    <TextView
        android:id="@+id/group_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="创建的文集"
        android:layout_marginLeft="7dp"
        />
</LinearLayout>
4.接下来画二级列表的布局item_child.xml,这里只有一个我们自定义的gridView,我们将它设置横向三个元素。


item_child.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="match_parent">

    <com.fantasychong.expandablelistviewgridview0228.MyGridView
        android:id="@+id/child_gv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3"
        android:paddingLeft="13dp"
        android:paddingRight="13dp"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        />

</LinearLayout>

5.接下来画gridview里每个元素的布局item_gv.xml,这里就一张图片。


item_gv.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/gv_iv"
        android:layout_width="150dp"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        />

</android.support.constraint.ConstraintLayout>

6.接下来比较重要的一步,我们要构建ExpandableListView的适配器ExpandableListAdapter

让ExpandableListAdapter继承BaseExpandableListAdapter实现一串方法,其中有个重要的方法,返回二级列表的item个数,因为只有一个gridView,所以我们手动给它返回1,否则会有多个gridview出现。

//返回二级列表的item个数,因为这里只有一个GridView,所以我们手动给它赋值1
@Override
public int getChildrenCount(int groupPosition) {
    return 1;
}

在getGroupView里,获取item_group.xml中的控件,当isExpand时,给imageview设置向下的图标,反之设置向上的图标。

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    if (convertView== null){
        convertView= LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_group, null);
    }
    ImageView arrow= convertView.findViewById(R.id.group_arrow);
    TextView title= convertView.findViewById(R.id.group_title);
    if (isExpanded){
        arrow.setImageResource(R.drawable.ic_group_open_normal);
    }else {
        arrow.setImageResource(R.drawable.ic_group_close_normal);
    }
        title.setText(groupList.get(groupPosition));
        return convertView;
    }

在getChildView里,我们在手动撸一个gridview的适配器GridViewAdapter,在这里给gridview设置setAdapter。

@Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView== null){
                convertView= LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_child, null);
            }
            gv= convertView.findViewById(R.id.child_gv);
            MyGridViewAdapter adapter= new MyGridViewAdapter(itemList.get(groupPosition));
            gv.setAdapter(adapter);
            return convertView;
        }

注意各个list的传递,别错乱了。

ExpandableListAdapter.java(内部含GridViewAdapter)

 class ExpandableListAdapter extends BaseExpandableListAdapter{

        private MyGridView gv;
        private List<String> groupList;
        private List<List<Integer>> itemList;


        public ExpandableListAdapter(List<String> groupList, List<List<Integer>> itemList) {
            this.groupList= groupList;
            this.itemList= itemList;
        }

        //返回一级列表的item个数
        @Override
        public int getGroupCount() {
            return groupList.size();
        }

        //返回二级列表的item个数,因为这里只有一个GridView,所以我们手动给它赋值1
        @Override
        public int getChildrenCount(int groupPosition) {
            return 1;
        }

        //返回一级列表的position
        @Override
        public Object getGroup(int groupPosition) {
            return groupList.get(groupPosition);
        }

        //返回二级列表的position
        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return itemList.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) {
            if (convertView== null){
                convertView= LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_group, null);
            }
            ImageView arrow= convertView.findViewById(R.id.group_arrow);
            TextView title= convertView.findViewById(R.id.group_title);
            if (isExpanded){
                arrow.setImageResource(R.drawable.ic_group_open_normal);
            }else {
                arrow.setImageResource(R.drawable.ic_group_close_normal);
            }
            title.setText(groupList.get(groupPosition));
            return convertView;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView== null){
                convertView= LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_child, null);
            }
            gv= convertView.findViewById(R.id.child_gv);
            MyGridViewAdapter adapter= new MyGridViewAdapter(itemList.get(groupPosition));
            gv.setAdapter(adapter);
            return convertView;
        }

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

        class MyGridViewAdapter extends BaseAdapter{

            private List<Integer> itemGridList3= new ArrayList<>();
            private ImageView pic;

            public MyGridViewAdapter(List<Integer> itemGridList3) {
                this.itemGridList3 = itemGridList3;
            }

            @Override
            public int getCount() {
                return itemGridList3.size();
            }

            @Override
            public Object getItem(int position) {
                return itemGridList3.get(position);
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView== null){
                    convertView= LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_gv, null);
                }
                pic= convertView.findViewById(R.id.gv_iv);
                pic.setImageResource(itemGridList3.get(position));
                return convertView;
            }
        }
    }

7.最后在MainActivity给各list添加下固定数据,设置Adapter即可。

/**
     * 初始化数据
     */
    private void initData() {
        groupList.add("创建的文集");
        groupList.add("收藏的文集和杂志");

        itemGridList.add(R.mipmap.ic_launcher);

        for (int i= 0; i< 5; i++){
            itemGridList2.add(R.mipmap.ic_launcher_round);
            itemGridList2.add(R.mipmap.ic_launcher_round);
            itemGridList2.add(R.mipmap.ic_launcher_round);
        }

        itemList.add(itemGridList);
        itemList.add(itemGridList2);

        ExpandableListAdapter adapter= new ExpandableListAdapter(groupList, itemList);
        elv.setAdapter(adapter);
    }

至此全部完成。

源码下载:点击打开链接



猜你喜欢

转载自blog.csdn.net/u014078990/article/details/79409760