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. Ubuntu使用wget下载jdk问题

    使用以下命令可下载成功,否则下载下来的可能是一个html文档. wget --no-cookies --no-check-certificate --header "Cookie:gpw_e ...

  2. Android sqlite 数据库在java代码中的增删改查

    private void queryPerson(PersonSQLiteOpenHelper personSQLiteOpenHelper) { SQLiteDatabase sqLiteDatab ...

  3. 【BZOJ1901】 Zju2112 Dynamic Rankings(树套树)

    [题意] 给定一个含有n个数的序列a[1],a[2],a[3]--a[n], 程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k ...

  4. 在html中嵌入markdown

    在博客园网页里写markdown的时候, 某些特殊内容想加上自定义的css, 于是用<div class="xxx">包裹起来, 但是发现该<div>中的m ...

  5. Lua的function、closure和upvalue

    Lua中的函数是一阶类型值(first-class value),定义函数就象创建普通类型值一样(只不过函数类型值的数据主要是一条条指令而已),所以在函数体中仍然可以定义函数.假设函数f2定义在函数f ...

  6. 【HDOJ】2149 Public Sale

    看Discuss说是博弈论,没学到这个分类.不过仔细想了想,发现.如果m<=n,那么可能结果为m,m+1...n.否则,如果m%(n+1) == 0,那么无论如何都会输,因为无论先报价什么数,如 ...

  7. git tag的使用

    查看所有的标签git tag 删除某一个标签git tag -d tagName 创建带注释的标签 git tag -a tagName -m "annotate" 轻量级标签 g ...

  8. c#中使用SESSION需要注意的几个问题

    C#的SESSION和其它程序中的SESSSION可能有一点的不同,下面讲下哪飞网程序员遇到的一个地方使用SESSION的问题.希望对大家有所帮助 一.在页面中用SESSION,存值session[& ...

  9. Node.js权威指南 (12) - Node.js中的其他模块

    12.1 使用dns模块解析域名 / 313 12.1.1 使用resolve方法将域名解析为DNS记录 / 313 12.1.2 使用lookup方法查询IP地址 / 315 12.1.3 使用re ...

  10. HDU-1701 Binary Tree Traversals

    http://acm.hdu.edu.cn/showproblem.php?pid=1710 已知先序和中序遍历,求后序遍历二叉树. 思路:先递归建树的过程,后后序遍历. Binary Tree Tr ...