Android ExpandableListView 中完美嵌套 GridView

来源:互联网 发布:java 守护进程 编辑:程序博客网 时间:2024/05/17 01:40

转载请注明出处: http://blog.csdn.net/like_program/article/details/52549435

在做项目的时候,想在 ExpandableListView 中嵌套一个 GridView,在实现的过程中,遇到了不少坑,所以写篇博客记录一下,也顺便帮助下和我一样的新手。

我一直觉得,再多的文字,再多的代码片段,都不如写个小 Demo 更直观,所以在以后的博客中,我都尽量用小 Demo 来讲解,也给出源码。

先上一张最终效果图:

完美嵌套

打开 Android Studio,我们新建一个 ExpandableListViewTest 项目,在项目中新建两个包(package), 分别命名为 activity 和 adapter,然后将 Android Studio 默认创建的 MainActivity 拖入 activity 包中。

为了让项目运行起来看上去更美观,我们用 Theme 主题,修改 AndroidManifest.xml 中的 application 下的 android:theme 属性,修改为@android:style/Theme, 
修改后的 AndroidManifest.xml 代码如下所示:

<application    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:supportsRtl="true"    android:theme="@android:style/Theme" >    <activity android:name=".activity.MainActivity" >        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity></application>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

修改了主题后,我们再修改下 MainActivity.Java 文件,MainActivity 默认继承自 AppCompatActivity ,我们把 AppCompatActivity 修改为 Activity,让 MainActivity 继承 Activity,这样等会项目才能正常运行。

我们先来写一下布局文件,既然我们想在 ExpandableListView 中嵌套一个 GridView,那么首先我们应该写一个 ExpandableListView

activity_main.xml 代码如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".activity.MainActivity">    <ExpandableListView        android:id="@+id/expandableList"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:childDivider="@drawable/separator"        android:divider="@drawable/separator"/></RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

布局文件非常简单,在布局中只放置了一个 ExpandableListView,并设置了各组之间的分割线和各组子项之间的分割线,分割线是一张图片。接下来我们就要在 MainActivity 中实例化 ExpandableListView 的布局,并准备好 ExpandableListView 要显示的数据,然后把数据传入 ExpandableListView 的适配器,这样才能把 ExpandableListView 显示出来。

MainActivity.java 代码如下所示:

package com.example.expandablelistviewtest.activity;import android.app.Activity;import android.os.Bundle;import android.widget.ExpandableListView;import com.example.expandablelistviewtest.R;import com.example.expandablelistviewtest.adapter.MyExpandableListViewAdapter;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity {    private ExpandableListView expandableListView;    /**     * 每个分组的名字的集合     */    private List<String> groupList;    /**     * 每个分组下的每个子项的 GridView 数据集合     */    private List<String> itemGridList;    /**     * 所有分组的所有子项的 GridView 数据集合     */    private List<List<String>> itemList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        expandableListView = (ExpandableListView) findViewById(R.id.expandableList);        // 分组        groupList = new ArrayList<>();        groupList.add("分组1");        groupList.add("分组2");        // 每个分组下的每个子项的 GridView 数据集合        itemGridList = new ArrayList<>();        for (int i = 0; i < 4; i++) {            itemGridList.add("电脑" + (i + 1));        }        // 所有分组的所有子项的 GridView 数据集合        itemList = new ArrayList<>();        itemList.add(itemGridList);        itemList.add(itemGridList);        // 创建适配器        MyExpandableListViewAdapter adapter = new MyExpandableListViewAdapter(MainActivity.this,                groupList, itemList);        expandableListView.setAdapter(adapter);        // 隐藏分组指示器        expandableListView.setGroupIndicator(null);        // 默认展开第一组        expandableListView.expandGroup(0);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

既然我们要设置 ExpandableListView 适配器,那首先我们要定义一个 ExpandableListView 适配器,在 adapter 包下新建一个 MyExpandableListViewAdapter.java 类,在 ExpandableListView 适配器中,我们将把在 MainActivity 中准备好的数据传入这个适配器,并定义这些数据该怎么显示,因此我们还要创建一个 ExpandableListView 的分组布局文件 和 子项布局文件。不过不要着急,我们先定义好适配器。

MyExpandableListViewAdapter.java 代码如下所示:

package com.example.expandablelistviewtest.adapter;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseExpandableListAdapter;import android.widget.GridView;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.example.expandablelistviewtest.R;import java.util.List;/** * ExpandableListView 适配器 */public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {    private Context mContext;    /**     * 每个分组的名字的集合     */    private List<String> groupList;    /**     * 所有分组的所有子项的 GridView 数据集合     */    private List<List<String>> itemList;    private GridView gridView;    public MyExpandableListViewAdapter(Context context, List<String> groupList,                                       List<List<String>> itemList) {        mContext = context;        this.groupList = groupList;        this.itemList = itemList;    }    @Override    public int getGroupCount() {        return groupList.size();    }    @Override    public int getChildrenCount(int groupPosition) {        return itemList.get(groupPosition).size();    }    @Override    public Object getGroup(int groupPosition) {        return groupList.get(groupPosition);    }    @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 (null == convertView) {            convertView = View.inflate(mContext, R.layout.expandablelist_group, null);        }        ImageView ivGroup = (ImageView) convertView.findViewById(R.id.iv_group);        TextView tvGroup = (TextView) convertView.findViewById(R.id.tv_group);        // 如果是展开状态,就显示展开的箭头,否则,显示折叠的箭头        if (isExpanded) {            ivGroup.setImageResource(R.drawable.ic_open);        } else {            ivGroup.setImageResource(R.drawable.ic_close);        }        // 设置分组组名        tvGroup.setText(groupList.get(groupPosition));        return convertView;    }    @Override    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View            convertView, ViewGroup parent) {        if (null == convertView) {            convertView = View.inflate(mContext, R.layout.expandablelist_item, null);        }        // 因为 convertView 的布局就是一个 GridView,        // 所以可以向下转型为 GridView        gridView = (GridView) convertView;        // 创建 GridView 适配器        MyGridViewAdapter gridViewAdapter = new MyGridViewAdapter(mContext, itemList.get                (groupPosition));        gridView.setAdapter(gridViewAdapter);        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                Toast.makeText(mContext, "点击了第" + (groupPosition + 1) + "组,第" +                        (position + 1) + "项", Toast.LENGTH_SHORT).show();            }        });        return convertView;    }    @Override    public boolean isChildSelectable(int groupPosition, int childPosition) {        return false;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125

我们可以看到,ExpandableListView 的适配器代码看上去很多,但实际上并不复杂,因为大部分代码都是重写父类的方法,这里对 getChildView 的某些代码解释一下:convertView 的布局就是一个 GridView,但是实例化布局后,convertView 是 View 类型,所以 convertView 没有 setAdapter() 方法,需要向下转型为 GridView ,才能调用 setAdapter() 方法,设置适配器。

定义好了 ExpandableListView 的适配器,我们来写一下 ExpandableListView 的分组布局文件 和 子项布局文件。我们先写 ExpandableListView 的分组布局文件,在 layout 文件夹下,新建 expandablelist_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:gravity="center_vertical"              android:orientation="horizontal">    <ImageView        android:id="@+id/iv_group"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:src="@drawable/ic_open"/>    <TextView        android:id="@+id/tv_group"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:gravity="center"        android:text="分组"        android:textSize="18sp"/></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

我们可以看到,分组布局非常简单,就是一个横向的线性布局,然后依次排列了一个 指示箭头 图片 和一个 分组 名字,我们继续写 ExpandableListView 的子项布局文件,在 layout 文件夹下,新建 expandablelist_item.xml ,代码如下所示:

<?xml version="1.0" encoding="utf-8"?><GridView xmlns:android="http://schemas.android.com/apk/res/android"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:numColumns="3"></GridView>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我们可以看到,子项布局更简单,就是一个有 3 列数据的 GridView。

对了,刚才我们在 ExpandableListView 的适配器中创建了 GridView 的适配器,那我们赶紧去定义一下 GridView 的适配器吧。

在 adapter 包下,新建 MyGridViewAdapter.java ,代码如下所示:

package com.example.expandablelistviewtest.adapter;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.expandablelistviewtest.R;import java.util.List;/** * GridView 适配器 */public class MyGridViewAdapter extends BaseAdapter {    private Context mContext;    /**     * 每个分组下的每个子项的 GridView 数据集合     */    private List<String> itemGridList;    public MyGridViewAdapter(Context mContext, List<String> itemGridList) {        this.mContext = mContext;        this.itemGridList = itemGridList;    }    @Override    public int getCount() {        return itemGridList.size();    }    @Override    public Object getItem(int position) {        return itemGridList.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if (null == convertView) {            convertView = View.inflate(mContext, R.layout.gridview_item, null);        }        TextView tvGridView = (TextView) convertView.findViewById(R.id.tv_gridview);        tvGridView.setText(itemGridList.get(position));        return convertView;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

GridView 的适配器和 ExpandableListView 的适配器一样,逻辑并不复杂,主要就是重写父类的方法,在 getView() 方法中,我们实例化了 GridView 的子项布局,所以,我们也要写一下 GridView 的子项布局文件,在 layout 文件夹中,新建 gridview_item.xml ,代码如下所示:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="vertical">    <TextView        android:id="@+id/tv_gridview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:drawableTop="@drawable/icon_computer"        android:gravity="center"        android:text="电脑"/></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

GridView 子项布局只定义了一个带有图片的 TextView。

好了,我们来运行一下,看看效果。

初步运行效果

好像已经成功了,不过貌似有些问题:

  1. 它的每个分组的每个子项里都有一个 GridView,但我们只想在每个分组里只显示一个 GridView 。
  2. 在点击 GridView 中的子项时,我们发现,在同一个分组里,点击不同子项里 GridView 的第一个子项时,都显示的第 N 组第 1 项。
  3. 我们定义的 GridView 有 4 个数据,分别是 电脑 1 ,电脑 2 ,电脑 3 ,电脑 4 。但是它只显示了 3 个。

我们逐一解决这些问题。

首先,我们可以发现,每组都有 4 行数据,也就是说,每组都有 4 个子项,那么如果我们想要在每个分组里只显示一个 GridView ,也就是一个子项,那么我们要先找到我们之前定义过的和 4 相关的数据,经过查找,我们发现,和 4 相关的数据只有一个,就是 itemGridList ,它里面有 4 个数据,找到了它之后,我们再找一下它在哪里被调用了,经过查找,我们发现,在 ExpandableListView 适配器中的 getChildrenCount() 方法中调用了它,有些同学了可能会疑惑,这里调用的是 itemList.get(groupPosition).size(),关 itemGridList 什么事,其实我们之前在 MainActivity 中是这样创建 itemList 的:itemList.add(itemGridList),在这行代码中,itemGridList 被添加到了 itemList 中,那么在 getChildrenCount() 方法中,调用itemList.get(groupPosition) ,得到的就是 itemGridList ,再调用它的 size() 方法,得到的就是 itemGridList 的大小了,也就是 4,知道了这个,我们想在每个分组里只显示一个 GridView,也就好办了,在 getChildrenCount() 方法中,我们直接返回 1,即

@Overridepublic int getChildrenCount(int groupPosition) {    return 1;}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

再运行一下程序,我们发现,果然每个分组里只显示了一个 GridView 。

每个分组只显示一个 GridView

我们再来看第二个问题,在同一个分组里,点击不同子项里 GridView 的第一个子项时,都显示的第 N 组第 1 项。

我们查看下 ExpandableListView 适配器代码中的 getChildView() 代码中的设置子项监听器代码:

Toast.makeText(mContext, "点击了第" + (groupPosition + 1) + "组,第" +                        (position + 1) + "项", Toast.LENGTH_SHORT).show();
  • 1
  • 2
  • 1
  • 2

这里使用了两个变量, groupPosition 很容易理解,就是 分组的 id ,position 可能有些同学会迷惑,position 并不是分组的子项 id ,而是 GridView 的子项 id ,弄清了这个,第二个问题也就不难懂了,我们不管点击的是分组下的哪一个子项中的 GridView 的第一项,都显示是 第一项,是因为 position 表示的 GridView 的子项 id ,和 分组下的子项 id 并没有关系。

我们再来看第三个问题,我们定义的 GridView 有 4 个数据,但是它只显示了 3 个。

首先,它只显示 3 个的部分原因是因为我们定义的 GridView 一行只能显示 3 个数据,我们可以查看 expandablelist_item.xml 的代码:android:numColumns="3"

更重要的原因是因为 GridView 的父容器测量模式为 UNSPECIFIED 的时候,GridView 的高度默认为一个 item 的高度,GridView 中源码如下:

if (heightMode == MeasureSpec.UNSPECIFIED) {    heightSize = mListPadding.top + mListPadding.bottom + childHeight +            getVerticalFadingEdgeLength() * 2;}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

既然是这样的话,我们就重写 GridView 的 onMeasure 方法,自定义高度,在 activity 包中,新建 MyGridView.java ,代码如下:

package com.example.expandablelistviewtest.activity;import android.content.Context;import android.util.AttributeSet;import android.widget.GridView;/** * 自定义 GridView */public class MyGridView extends GridView {    public MyGridView(Context context) {        super(context);    }    public MyGridView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    /**     * 重写该方法,达到使 GridView 适应 ExpandableListView 的效果     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, expandSpec);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

关于重写 GridView 的 onMeasure 方法的原理分析,可以查看这两篇文章。

android开发游记:ScrollView嵌套ListView,ListView完全展开及makeMeasureSpec测量机制原理分析

详解嵌套ListView、ScrollView布局显示不全的问题

写好了 MyGridView 后,在 MyGridView 上点击右键,选择 Copy Reference,复制 MyGridView 的全路径名,替换 expandablelist_item.xml 中的 GridView 标签。

复制 GridView 全路径名

替换后的 expandablelist_item.xml 代码如下:

<?xml version="1.0" encoding="utf-8"?><com.example.expandablelistviewtest.activity.MyGridView    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:numColumns="3"></com.example.expandablelistviewtest.activity.MyGridView>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

重新运行程序,我们发现,GridView 已经完美嵌套在 ExpandableListView 中了。

完美嵌套

源码下载

0 0
原创粉丝点击