1. ExpandableListView是一个用来显示二级节点的ListView。

比如如下效果的界面:

2. 使用ExpandableListView步骤:

(1)要给ExpandableListView设置适配器,那么必须先设置数据源;

(2)数据源,就是此处的适配器类ExpandableAdapter,此方法继承了BaseExpandableListAdapter,它是ExpandableListView的一个子类。需要重写里面的多个方法。getChildView()和getGroupView()方法设置自定义的布局;

(3)数据源设置好,直接给ExpandableListView.setAdapter()即可实现收缩功能。

3.下面就是我们就利用具体的案例来说明如何使用这个ExpandableListView组件:

(1)首先我们定义我们的布局文件activity_main.xml 如下:

<LinearLayout 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"
android:orientation="vertical"
tools:context="com.himi.expandablelistview.MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="QQ通讯录"
android:textSize="30sp"
android:textColor="#55ff0000"
android:gravity="center_horizontal"
/> <ExpandableListView
android:id="@+id/expandablelv"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ExpandableListView> </LinearLayout>

在这个activity_main.xml布局文件中,我们引入了组件ExpandableListView,布局效果图如下:

(2)定义我们自己的适配器MyExpandablelistviewAdapter,让它继承自BaseExpandableListAdapter,然后实现继承的方法。这里我们直接把数据源放在了我们自定义的类MyExpandablelistviewAdapter之中,然后绑定这个数据源到我们定的MyExpandablelistviewAdapter之中。

数据源我们定义为:

    private String[] groups = {"家人","同学","同事"};
private String[][] childs = { {"老爸","老妈"}, {"刘德华","黎明","郭富城","张学友"}, {"马云","比尔盖茨",
"巴菲特"} };
private int[][] childs_imgs = { { R.drawable.img1, R.drawable.img2 },
{ R.drawable.img3, R.drawable.img4 , R.drawable.img5, R.drawable.img6},
{ R.drawable.img7, R.drawable.img8 , R.drawable.img9}
};

MVC模式:在Android项目中,业务逻辑,数据处理等担任了Model(模型)角色,XML界面显示等担任了View(视图)角色,Activity担任了Contronller(控制器)角色。contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。

这里的MyExpandablelistviewAdapter.java:

package com.himi.expandablelistview.adpater;

import android.view.ViewGroup.LayoutParams;
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.himi.expandablelistview.R; /**
* 自定义适配器MyExpandablelistviewAdapter
* @author Administrator
*
*/
public class MyExpandablelistviewAdapter extends BaseExpandableListAdapter {
private Context context ;
private String[] groups = {"家人","同学","同事"};
private String[][] childs = { {"老爸","老妈"}, {"刘德华","黎明","郭富城","张学友"}, {"马云","比尔盖茨",
"巴菲特"} };
private int[][] childs_imgs = { { R.drawable.img1, R.drawable.img2 },
{ R.drawable.img3, R.drawable.img4 , R.drawable.img5, R.drawable.img6},
{ R.drawable.img7, R.drawable.img8 , R.drawable.img9}
}; //引入一个字段context,方便Activity实例化MyExpandablelistviewAdapter
public MyExpandablelistviewAdapter(Context context) {
this.context = context;
} //获取一级菜单的分组数目,比如这里就是3组:"我的好友","同学","同事"
public int getGroupCount() {
return groups.length;
} //获取每个一节菜单中二级菜单的分组数目,比如"家人"中有2个条目("老爸","老妈")
public int getChildrenCount(int groupPosition) {
return childs[groupPosition].length;
}
//获取每个一级菜单子项对象
public String getGroup(int groupPosition) {
return groups[groupPosition];
}
//获取每个二级菜单子项对象
public String getChild(int groupPosition, int childPosition) {
return childs[groupPosition][childPosition];
} //获取每个一级菜单子项对象Id
public long getGroupId(int groupPosition) {
return groupPosition;
}
//获取每个二级菜单子项对象Id
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
} /**
* hasStableIds有关于MyExpandablelistviewAdapter适配器刷新顺序
* getGroupId和getChildId两个方法获取对象Id,获取到的Id,ExpandableListView会根据这个Id确定位置显示内容
* 然而Id是否有效稳定是由hasStableIds决定的,也就是说:这个方法就是判断item的id是否稳定,
* 如果有自己的id也就是true,那就是稳定,否则不稳定,则根据item位置来确定id
*
*/
public boolean hasStableIds() {
return true;
} //渲染一级菜单
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if(convertView == null) {
/**
* LayoutInflater是一个抽象类,它的inflate方法可以把一个xml文件转化为View对象
* 对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入
* 刚刚说明了:LayoutInflater是一个抽象类,要获取LayoutInflater的实例;
* 获得 LayoutInflater 实例的三种方式:
* 1.LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
*
* 2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
*
* 3. LayoutInflater inflater = LayoutInflater.from(context);
* 上面三种方法的本质是一样的
*/
LayoutInflater minflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = minflater.inflate(R.layout.group_item,null);
}
TextView tv = (TextView) convertView.findViewById(R.id.textview_group);
tv.setText(groups[groupPosition]);
tv.setTextSize(25);
tv.setPadding(15, 5, 0, 0);
return convertView;
}
//渲染二级菜单
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater minflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = minflater.inflate(R.layout.child_item,null);
}
ImageView iv = (ImageView) convertView.findViewById(R.id.imageview_child);
TextView tv = (TextView) convertView.findViewById(R.id.textview_child); iv.setImageResource(childs_imgs[groupPosition][childPosition]);
//导入的包为:import android.view.ViewGroup.LayoutParams;
LayoutParams params = iv.getLayoutParams();
params.width = 200;
params.height = 200;
iv.setLayoutParams(params); tv.setText(childs[groupPosition][childPosition]);
//记得return convertView
return convertView;
} //true:让子项可选 ; false:让子项不可选
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
} }

(3)最后在MainActivity.java中绑定我们定义的MyExpandablelistviewAdapter(此时的适配器已经绑定了数据源,适配器可以控制其相应的显示),这使用我们还需要绑定适配器到模型Model,就是说绑定适配器到ExpandableListView:

这里的MainActivity.java:

package com.himi.expandablelistview;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast; import com.himi.expandablelistview.adpater.MyExpandablelistviewAdapter; public class MainActivity extends Activity {
private ExpandableListView expan_listview; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expan_listview = (ExpandableListView) findViewById(R.id.expandablelv);
expan_listview.setAdapter(new MyExpandablelistviewAdapter(this));
expan_listview.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) { Toast.makeText(MainActivity.this, "你点击的是第"+(groupPosition+1)+"的菜单下的第"+(childPosition+1)+"选项", 0).show();
return false;
}
});
} }

这里我们添加了一个ExpandableListView的点击事件:expan_listview. setOnChildClickListener;当然这里还有其他很多监听事件,这里我们不多加详解,我们只要知道灵魂就行了。

(4)运行结果图如下:

Android 高级UI设计笔记01:使用ExpandableListView组件(ListView的扩展)的更多相关文章

  1. Android 高级UI设计笔记07:RecyclerView 的详解

    1. 使用RecyclerView       在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...

  2. Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)

    Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...

  3. Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item

    1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item: (1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有 ...

  4. Android 高级UI设计笔记06:仿微信图片选择器(转载)

    仿微信图片选择器: 一.项目整体分析: 1. Android加载图片的3个目标: (1)尽可能的去避免内存溢出. a. 根据图片的显示大小去压缩图片 b. 使用缓存对我们图片进行管理(LruCache ...

  5. Android 高级UI设计笔记21:Android SegmentView(分段选择控件)

    1. 分段控制(SegmentView) 首先我们先看看什么是SegmentView的效果,如下: 分段控制这个View控件是ios7的分段控制,和QQ消息页面顶部的效果一样,android没有这个控 ...

  6. Android 高级UI设计笔记19:PopupWindow使用详解

    1. PopupWindow使用 PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的. 2. PopupWindow使用 ...

  7. Android 高级UI设计笔记17:Android在非UI线程中显示Toast

    1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...

  8. Android 高级UI设计笔记14:Gallery(画廊控件)之 3D图片浏览

    1. 利用Gallery组件实现 3D图片浏览器的功能,如下: 2. 下面是详细的实现过程如下: (1)这里我是测试性代码,我的图片是自己添加到res/drawable/目录下的,如下: 但是开发中不 ...

  9. Android 高级UI设计笔记09:Android如何实现无限滚动列表

    ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们提供了一个良好,整洁的用户体验 ...

随机推荐

  1. TortoiseSVN下载,安装,配置,常用操作 svn教程

    一. 首先在百度搜索并下载 TortoiseSVN 推荐从官网下载,软件分为32位和64位版本,下载时请根据自己的系统位数进行下载:

  2. windows 挂载windows 共享盘为本地磁盘

    我们在设置数据库自动备份时,为了数据的安全往往需要直接将数据备份到远程服务器上.在Linux可以通过NFS挂载来实现,在Windows平台可以直接通过net use+subst来实现将远程服务器的目录 ...

  3. 【HDOJ】1867 A + B for you again

    KMP算法的应用. #include <stdio.h> #include <string.h> #define MAXNUM 100005 char src[MAXNUM], ...

  4. PrintWriter out = response.getWriter() 输出中文乱码问题

    HttpServletResponse response = ServletActionContext.getResponse();        response.setCharacterEncod ...

  5. 论SOA架构的几种主要开发方式【转】

           面向服务架构soa以其独特的优势越来越受到企业的重视,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署.组合和使用.服务层是SOA的基础,可以直接被应用调用,从而有效控制系 ...

  6. Good Numbers

    Problem Description If we sum up every digit of a number and the result can be exactly divided by 10 ...

  7. ubuntu14.04 swap not avalible交换分区不能使用

    系统最近特别卡,打开"System monitor"中的resource发现"swap not avalibe".原来系统每交换分区. 我的是笔记本电脑,存储空间有限.首先我下载磁盘分区工具Gpart ...

  8. 转载:在Ubuntu系统下装Win7并引导双系统

    转载自http://blog.sina.com.cn/s/blog_9f6451990101blef.html 本人的系统原先是就单ubuntu系统,而且是未分区情况下自动安装的,现在又装了个wind ...

  9. Axure RP 8.0 中继器初体验

    为了解决增删等复杂交互的问题,中继器是个不错的选择. 拖拽出一个默认的中继器 中继器的数据集感觉就像是数据库一样,在右边检视窗口中可以看到中继器的默认数据集,可以理解成一张二维表.默认有1列,现成的3 ...

  10. advanced dom scripting dynamic web design techniques Chapter 2 CREATING YOUR OWN REUSABLE OBJECTS

    JavaScript is all about objects. Objects are the foundation of everything, so if you’re unfamiliar w ...