继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Android零基础入门第48节:可折叠列表ExpandableListView

繁星淼淼
关注TA
已关注
手记 298
粉丝 44
获赞 264

上一期学习了AutoCompleteTextView和MultiAutoCompleteTextView,你已经掌握了吗?本期开始学习ExpandableListView的使用。

一、认识ExpandableListView

    ExpandableListView 是 ListView 的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组里又可包含多个列表项。

    ExpandableListView的用法与普通 ListView的用法非常相似,只是 ExpandableListView所显示的列表项应 该由 ExpandableListAdapter 提供。ExpandableListAdapter 也是一个接口,该接口下提供的类继承关系图如下图所示。

                                              

    与Adapter类似的是,实现 ExpandableListAdapter也有如下三种常用方式。

·         扩展 BaseExpandableListAdapter 实现 ExpandableListAdapter。

·         使用 SimpleExpandableListAdapter 将两个 List 集合包装成 ExpandableListAdapter。

·         使用 SimpleCursorTreeAdapter 将 Cursor 中的数据包装成 SimpleCursorTreeAdapter。 

    ExpandableListView支持的常用XML属性如下:

·         android:childDivider:指定各组内子类表项之间的分隔条,图片不会完全显示, 分离子列表项的是一条直线。

·         android:childIndicator:显示在子列表旁边的Drawable对象,可以是一个图像。

·         android:childIndicatorEnd:子列表项指示符的结束约束位置。

·         android:childIndicatorLeft:子列表项指示符的左边约束位置。

·         android:childIndicatorRight:子列表项指示符的右边约束位置。

·         android:childIndicatorStart:子列表项指示符的开始约束位置。

·         android:groupIndicator:显示在组列表旁边的Drawable对象,可以是一个图像。

·         android:indicatorEnd:组列表项指示器的结束约束位置。

·         android:indicatorLeft:组列表项指示器的左边约束位置。

·         android:indicatorRight:组列表项指示器的右边约束位置。

·         android:indicatorStart:组列表项指示器的开始约束位置。

二、ExpandableListView 示例

    接下来通过一个简单的示例程序来学习ExpandableListView的使用方法。

    继续使用WidgetSample工程的listviewsample模块,在app/main/res/layout/目录下创建expandlist_layout.xml文件,在其中填充如下代码片段:

[代码]xml代码:

?

01

02

03

04

05

06

07

08

09

10

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

                android:layout_width="match_parent"

                android:layout_height="match_parent"  >

 

    <ExpandableListView

        android:id="@+id/expendlist"

        android:layout_width="match_parent"

        android:layout_height="match_parent" />

</RelativeLayout>

    在res/layout/目录创建expendlist_group.xml文件,代码如下:

[代码]xml代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

                android:layout_width="match_parent"

                android:layout_height="70dp"

                android:gravity="center_vertical"

                android:padding="10dp">

 

    <ImageView

        android:id="@+id/group_img"

        android:layout_width="36dp"

        android:layout_height="36dp"

        android:layout_centerVertical="true"

        android:layout_marginLeft="20dp"

        android:src="@drawable/group_close" />

 

    <TextView

        android:id="@+id/groupname_tv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerVertical="true"

        android:layout_toRightOf="@+id/group_img"

        android:layout_marginLeft="10dp"

        android:text="张三"

        android:textSize="18sp" />

</RelativeLayout>

    在res/layout/目录创建expendlist_item.xml文件,代码如下:

[代码]xml代码:

?

01

02

03

04

05

06

07

08

09

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

<?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="70dp"

              android:orientation="horizontal"

              android:gravity="center_vertical"

              android:padding="10dp" >

 

    <ImageView

        android:id="@+id/icon_img"

        android:layout_width="48dp"

        android:layout_height="48dp"

        android:layout_marginLeft="20dp"

        android:src="@drawable/item" />

 

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="60dp"

        android:gravity="center_vertical"

        android:orientation="vertical" >

 

        <TextView

            android:id="@+id/itemname_tv"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:textSize="22sp"

            android:textStyle="bold"

            android:text="李大钊" />

 

        <TextView

            android:id="@+id/info_tv"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_marginTop="10dp"

            android:text="今天是个好日子啊!" />

    </LinearLayout>

</LinearLayout>

    新建MyExpandableListViewAdapter类,继承ExpandableListViewAdapter,并重写其方法,代码如下:

[代码]java代码:

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

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

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

package com.jinyu.cqkxzsxy.android.listviewsample.adapter;

 

 

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseExpandableListAdapter;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.jinyu.cqkxzsxy.android.listviewsample.R;

 

import java.util.List;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert

 */

public class MyExpandableListViewAdapter   extends BaseExpandableListAdapter   {

    private Context mContext = null;

    private List<string> mGroupList = null;

    private List<list<string>> mItemList   = null;

 

    public MyExpandableListViewAdapter(Context   context, List<string> groupList,

                                       List<list<string>>   itemList) {

        this.mContext   = context;

        this.mGroupList   = groupList;

        this.mItemList   = itemList;

    }

 

    /**

     * 获取组的个数

     *

     * @return

     * @see   android.widget.ExpandableListAdapter#getGroupCount()

     */

    @Override

    public int getGroupCount() {

        return mGroupList.size();

    }

 

    /**

     * 获取指定组中的子元素个数

     *

     * @param   groupPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#getChildrenCount(int)

     */

    @Override

    public int getChildrenCount(int groupPosition) {

        return mItemList.get(groupPosition).size();

    }

 

    /**

     * 获取指定组中的数据

     *

     * @param   groupPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#getGroup(int)

     */

    @Override

    public String getGroup(int groupPosition) {

        return mGroupList.get(groupPosition);

    }

 

    /**

     * 获取指定组中的指定子元素数据。

     *

     * @param   groupPosition

     * @param   childPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#getChild(int, int)

     */

    @Override

    public String getChild(int groupPosition, int childPosition) {

        return mItemList.get(groupPosition).get(childPosition);

    }

 

    /**

     * 获取指定组的ID,这个组ID必须是唯一的

     *

     * @param   groupPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#getGroupId(int)

     */

    @Override

    public long getGroupId(int groupPosition) {

        return groupPosition;

    }

 

    /**

     * 获取指定组中的指定子元素ID

     *

     * @param   groupPosition

     * @param   childPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#getChildId(int, int)

     */

    @Override

    public long getChildId(int groupPosition, int childPosition) {

        return childPosition;

    }

 

    /**

     * 获取显示指定组的视图对象

     *

     * @param   groupPosition 组位置

     * @param   isExpanded    该组是展开状态还是伸缩状态

     * @param   convertView   重用已有的视图对象

     * @param   parent        返回的视图对象始终依附于的视图组

     * @return

     * @see   android.widget.ExpandableListAdapter#getGroupView(int, boolean,   android.view.View,

     *   android.view.ViewGroup)

     */

    @Override

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,

                             ViewGroup   parent) {

        GroupHolder   groupHolder = null;

        if (convertView == null) {

            convertView   = LayoutInflater.from(mContext).inflate(R.layout.expendlist_group, null);

            groupHolder   = new GroupHolder();

            groupHolder.groupNameTv   = (TextView) convertView.findViewById(R.id.groupname_tv);

            groupHolder.groupImg   = (ImageView) convertView.findViewById(R.id.group_img);

            convertView.setTag(groupHolder);

        }   else {

            groupHolder   = (GroupHolder) convertView.getTag();

        }

 

        if (isExpanded) {

            groupHolder.groupImg.setImageResource(R.drawable.group_open);

        }   else {

            groupHolder.groupImg.setImageResource(R.drawable.group_close);

        }

        groupHolder.groupNameTv.setText(mGroupList.get(groupPosition));

 

        return convertView;

    }

 

    /**

     * 获取一个视图对象,显示指定组中的指定子元素数据。

     *

     * @param   groupPosition 组位置

     * @param   childPosition 子元素位置

     * @param   isLastChild   子元素是否处于组中的最后一个

     * @param   convertView   重用已有的视图(View)对象

     * @param   parent        返回的视图(View)对象始终依附于的视图组

     * @return

     * @see   android.widget.ExpandableListAdapter#getChildView(int, int, boolean,   android.view.View,

     *   android.view.ViewGroup)

     */

    @Override

    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,

                             View   convertView, ViewGroup parent) {

        ItemHolder   itemHolder = null;

        if (convertView == null) {

            convertView   = LayoutInflater.from(mContext).inflate(R.layout.expendlist_item, null);

            itemHolder   = new ItemHolder();

            itemHolder.nameTv   = (TextView) convertView.findViewById(R.id.itemname_tv);

            itemHolder.iconImg   = (ImageView) convertView.findViewById(R.id.icon_img);

            convertView.setTag(itemHolder);

        }   else {

            itemHolder   = (ItemHolder) convertView.getTag();

        }

        itemHolder.nameTv.setText(mItemList.get(groupPosition).get(childPosition));

        itemHolder.iconImg.setBackgroundResource(R.drawable.item);

 

        return convertView;

    }

 

    /**

     * 组和子元素是否持有稳定的ID,也就是底层数据的改变不会影响到它们。

     *

     * @return

     * @see   android.widget.ExpandableListAdapter#hasStableIds()

     */

    @Override

    public boolean hasStableIds() {

        return true;

    }

 

    /**

     * 是否选中指定位置上的子元素。

     *

     * @param   groupPosition

     * @param   childPosition

     * @return

     * @see   android.widget.ExpandableListAdapter#isChildSelectable(int, int)

     */

    @Override

    public boolean isChildSelectable(int groupPosition, int childPosition) {

        return true;

    }

 

 

    class GroupHolder {

        public TextView groupNameTv;

        public ImageView groupImg;

    }

 

    class ItemHolder {

        public ImageView iconImg;

        public TextView nameTv;

    }

}

</list<string></string></list<string></string>

    上面程序的关键代码就是扩展BaseExpandableListAdapter来实现ExpandableListAdapter, 当扩展BaseExpandableListAdapter时,关键是实现如下4个方法。

·         getGroupCount():该方法返回包含的组列表项的数量。

·         getGroupView():该方法返回的View对象将作为组列表项。

·         getChildrenCount():该方法返回特定组所包含的子列表项的数量。

·         getChildView():该方法返回的View对象将作为特定组、特定位置的子列表项。

    新建ExpandableListActivity.java文件,加载上面新建的布局文件,具体代码如下:

[代码]java代码:

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

package com.jinyu.cqkxzsxy.android.listviewsample;

 

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.ExpandableListView;

import android.widget.Toast;

 

import com.jinyu.cqkxzsxy.android.listviewsample.adapter.MyExpandableListViewAdapter;

 

import java.util.ArrayList;

import java.util.List;

 

public class ExpandableListActivity   extends AppCompatActivity   {

    private ExpandableListView mExpandableListView = null;

    // 列表数据

    private List<string> mGroupNameList = null;

    private List<list<string>>   mItemNameList = null;

    // 适配器

    private MyExpandableListViewAdapter mAdapter = null;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.expandlist_layout);

 

        //   获取组件

        mExpandableListView   = (ExpandableListView) findViewById(R.id.expendlist);

        mExpandableListView.setGroupIndicator(null);

 

        //   初始化数据

        initData();

 

        //   为ExpandableListView设置Adapter

        mAdapter   = new MyExpandableListViewAdapter(this,   mGroupNameList, mItemNameList);

        mExpandableListView.setAdapter(mAdapter);

 

        //   监听组点击

        mExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener()   {

            @Override

            public boolean onGroupClick(ExpandableListView parent, View v,

                                        int groupPosition, long id) {

                if (mGroupNameList.get(groupPosition).isEmpty())   {

                    return true;

                }

                return false;

            }

        });

 

        //   监听每个分组里子控件的点击事件

        mExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener()   {

            @Override

            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,

                                        int childPosition, long id) {

                Toast.makeText(ExpandableListActivity.this,

                        mAdapter.getGroup(groupPosition)   + ":"

                                +    mAdapter.getChild(groupPosition, childPosition) ,

                        Toast.LENGTH_SHORT).show();

                return false;

            }

        });

    }

 

    // 初始化数据

    private void initData(){

        //   组名

        mGroupNameList   = new ArrayList<string>();

        mGroupNameList.add("历代帝王");

        mGroupNameList.add("华坛明星");

        mGroupNameList.add("国外明星");

        mGroupNameList.add("政坛人物");

 

        mItemNameList   = new  ArrayList<list<string>>();

        //   历代帝王组

        List<string>   itemList = new ArrayList<string>();

        itemList.add("唐太宗李世民");

        itemList.add("秦始皇嬴政");

        itemList.add("汉武帝刘彻");

        itemList.add("明太祖朱元璋");

        itemList.add("宋太祖赵匡胤");

        mItemNameList.add(itemList);

        //   华坛明星组

        itemList   = new ArrayList<string>();

        itemList.add("范冰冰 ");

        itemList.add("梁朝伟");

        itemList.add("谢霆锋");

        itemList.add("章子怡");

        itemList.add("杨颖");

        itemList.add("张柏芝");

        mItemNameList.add(itemList);

        //   国外明星组

        itemList   = new ArrayList<string>();

        itemList.add("安吉丽娜•朱莉");

        itemList.add("艾玛•沃特森");

        itemList.add("朱迪•福斯特");

        mItemNameList.add(itemList);

        //   政坛人物组

        itemList   = new ArrayList<string>();

        itemList.add("唐纳德•特朗普");

        itemList.add("金正恩");

        itemList.add("奥巴马");

        itemList.add("普京");

        mItemNameList.add(itemList);

    }

}

</string></string></string></string></string></list<string></string></list<string></string>

    上述代码为ExpandableListView设置Adapter,并为ExpandableListView设置事件监听器。

    修改程序启动的Activity,运行程序,可以看到下图所示界面效果。

    点击组的时候,会将其子元素打开,如上图右侧所示,单击其中的列表会弹出消息提示。

    至此,关于ExpandableListView的简单使用学习完毕,更多属性和方法建议多加练习并掌握。

    今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

原文链接:http://www.apkbus.com/blog-205190-68762.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP