Android ExpandableListView BaseExpandableListAdapter (类似QQ分组列表)
分组列表视图(ExpandableListView)
和ListView不同的是它是一个两级的滚动列表视图,每一个组可以展开,显示一些子项,类似于
QQ列表,这些项目来至于ExpandableListAdapter的子类,也就是说,要实现向里面添加项目,必
须写一个子类实现ExpandableListAdapter的接口或者使用系统为我们实现在子类
常用属性
1. android:childDivider 指定各组内子类表项之间的分隔条,
2. android:childIndicator 显示在子列表旁边的Drawable对象
3. android:childIndicatorLeft 子列表项指示符的左边约束位置
4. android:childIndicatorRight 子列表项指示符的右边约束位置
5. android:groupIndicator 显示在组列表旁边的Drawable对象
6. android:indicatorLeft 组列表项指示器的左边约束位置
7. android:indicatorRight 组列表项指示器的右边约束位置
一般适用于ExpandableListView的Adapter都要继承BaseExpandableListAdapter这个类,
并且必须重载getGroupView和getChildView这两个最为重要的方法。
当扩展BaseExpandableListAdapter时,要实现全部方法,关键是实现其中的四个方法。
1、首相activity_main.xml布局搭建
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ExpandableListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/elv"/> </RelativeLayout>
activity_main.xml
2、然后是搭建QQ分组的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <TextView
android:id="@+id/groupName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="分组名称" /> <TextView
android:id="@+id/groupOnline"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0/8" /> </RelativeLayout>
item_group.xml
3、再搭建分组中各选项的布局(QQ联系人,包括头像,昵称,签名)
这里由于引用了外部的自定义的控件,所以这里包名加类名
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal" > <com.test.lesson7_expandablelistview.CircleImageView
android:id="@+id/img"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ic_launcher" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" > <TextView
android:id="@+id/nickName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="昵称"
android:textSize="18sp" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" > <TextView
android:id="@+id/online"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[在线]" /> <TextView
android:id="@+id/sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="我要飞的更高~" />
</LinearLayout>
</LinearLayout> </LinearLayout>
item_child.xml
4、圆角图片形状
在res/values中建circle_attr.xml
<resources>
<declare-styleable name="CircularImage">
<attr name="border_width" format="dimension" />
<attr name="border_color" format="color" />
</declare-styleable>
</resources>
5、然后新建一个CircleImageView继承ImageView
此处自定义控件是在GitHub上下载
public class CircleImageView extends ImageView {
private static final Xfermode MASK_XFERMODE;
private Bitmap mask;
private Paint paint;
private int mBorderWidth = 10;
private int mBorderColor = Color.parseColor("#f2f2f2");
private boolean useDefaultStyle = false;
static {
PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
MASK_XFERMODE = new PorterDuffXfermode(localMode);
}
public CircleImageView(Context context) {
super(context);
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CircularImage);
mBorderColor = a.getColor(R.styleable.CircularImage_border_color,
mBorderColor);
final int def = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
mBorderWidth = a.getDimensionPixelOffset(
R.styleable.CircularImage_border_width, def);
a.recycle();
}
private void useDefaultStyle(boolean useDefaultStyle) {
this.useDefaultStyle = useDefaultStyle;
}
@Override
protected void onDraw(Canvas canvas) {
if (useDefaultStyle) {
super.onDraw(canvas);
return;
}
final Drawable localDraw = getDrawable();
if (localDraw == null) {
return;
}
if (localDraw instanceof NinePatchDrawable) {
return;
}
if (this.paint == null) {
final Paint localPaint = new Paint();
localPaint.setFilterBitmap(false);
localPaint.setAntiAlias(true);
localPaint.setXfermode(MASK_XFERMODE);
this.paint = localPaint;
}
final int width = getWidth();
final int height = getHeight();
int layer = canvas.saveLayer(0.0F, 0.0F, width, height, null, 31);
localDraw.setBounds(0, 0, width, height);
localDraw.draw(canvas);
if ((this.mask == null) || (this.mask.isRecycled())) {
this.mask = createOvalBitmap(width, height);
}
canvas.drawBitmap(this.mask, 0.0F, 0.0F, this.paint);
canvas.restoreToCount(layer);
drawBorder(canvas, width, height);
}
private void drawBorder(Canvas canvas, final int width, final int height) {
if (mBorderWidth == 0) {
return;
}
final Paint mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
canvas.drawCircle(width / 2, height / 2, (width - mBorderWidth) / 2,
mBorderPaint);
canvas = null;
}
public Bitmap createOvalBitmap(final int width, final int height) {
Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
Bitmap localBitmap = Bitmap.createBitmap(width, height, localConfig);
Canvas localCanvas = new Canvas(localBitmap);
Paint localPaint = new Paint();
final int padding = (mBorderWidth - 3) > 0 ? mBorderWidth - 3 : 1;
RectF localRectF = new RectF(padding, padding, width - padding, height
- padding);
localCanvas.drawOval(localRectF, localPaint);
return localBitmap;
}
}
CircleImageView
6、创建Group类
public class Group {
//分组名
public String groupName;
//有很多User
public List<User> list;
public Group(String groupName){
this.groupName = groupName;
list = new ArrayList<User>();
}
//添加User
public void addUser(User user){
list.add(user);
}
//获取某个分组中User的数量
public int getChildCount() {
return list.size();
}
//获取某个分组中User在线的数量
public int getOnlineCount(){
int sum = 0;
for (User user : list) {
if(user.isOnline()){
sum++;
}
}
return sum;
}
//获取分组中某个孩子
public User getChild(int childPosition) {
return list.get(childPosition);
}
}
Group.java
7、创建User类
public class User {
private int imgId;
private String nickName;
private boolean isOnline;
private String sign;
public User() {
super();
}
public User(int imgId, String nickName, boolean isOnline, String sign) {
super();
this.imgId = imgId;
this.nickName = nickName;
this.isOnline = isOnline;
this.sign = sign;
}
public int getImgId() {
return imgId;
}
public void setImgId(int imgId) {
this.imgId = imgId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public boolean isOnline() {
return isOnline;
}
public void setOnline(boolean isOnline) {
this.isOnline = isOnline;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}
User
8、设置适配器
public class GroupAdapter extends BaseExpandableListAdapter{
Context context;
List<Group> list;
public GroupAdapter(Context context, List<Group> list) {
this.context = context;
this.list = list;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
GroupHolder holder;
if(convertView == null){
convertView = View.inflate(context, R.layout.item_grouplayout, null);
holder = new GroupHolder(convertView);
convertView.setTag(holder);
}else{
holder = (GroupHolder) convertView.getTag();
}
//设置数据
Group group = getGroup(groupPosition);
holder.groupName.setText(group.groupName);
holder.groupOnline.setText(group.getOnlineCount()+"/"+getChildrenCount(groupPosition));
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder;
if(convertView == null){
convertView = View.inflate(context, R.layout.item_childlayout, null);
holder = new ChildHolder(convertView);
convertView.setTag(holder);
}else{
holder = (ChildHolder) convertView.getTag();
}
//设置数据
User user = getGroup(groupPosition).getChild(childPosition);
holder.img.setImageResource(user.getImgId());
holder.nickName.setText(user.getNickName());
holder.online.setText(user.isOnline()?"[在线]":"[离线]");
holder.sign.setText(user.getSign());
return convertView;
}
class GroupHolder{
TextView groupName;
TextView groupOnline;
public GroupHolder(View convertView){
groupName = (TextView) convertView.findViewById(R.id.groupName);
groupOnline = (TextView) convertView.findViewById(R.id.groupOnline);
}
}
class ChildHolder{
ImageView img;
TextView nickName;
TextView online;
TextView sign;
public ChildHolder(View convertView){
img = (ImageView) convertView.findViewById(R.id.img);
nickName = (TextView) convertView.findViewById(R.id.nickName);
online = (TextView) convertView.findViewById(R.id.online);
sign = (TextView) convertView.findViewById(R.id.sign);
}
}
@Override
public int getGroupCount() {
return list.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return list.get(groupPosition).getChildCount();
}
@Override
public Group getGroup(int groupPosition) {
return list.get(groupPosition);
}
@Override
public User getChild(int groupPosition, int childPosition) {
return list.get(groupPosition).getChild(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
GroupAdapter
9、MainActivity.java中将所有组件找到,初始化数据源,并给ListView设置适配器
public class MainActivity extends Activity {
ExpandableListView elv;
private List<Group> list = new ArrayList<Group>();
int[] img = new int[6];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
elv = (ExpandableListView) findViewById(R.id.elv);
GroupAdapter adapter = new GroupAdapter(getBaseContext(), list);
elv.setAdapter(adapter);
}
private void initData() {
for (int i = 0; i < img.length; i++) {
try {
img[i] = R.drawable.class.getField("img0"+(i+1)).getInt(null);
} catch (Exception e) {
e.printStackTrace();
}
}
Group group1 = new Group("贵圈好乱");
group1.addUser(new User(img[0], "张翰", true, "我爱娜扎!"));
group1.addUser(new User(img[1], "郑爽", false, "妈蛋,要么瘦,要么死!"));
group1.addUser(new User(img[2], "胡彦斌", true, "其实我只是长得抽象了"));
group1.addUser(new User(img[5], "撒贝宁", true, "子怡当年没选择我是个美丽的错误"));
group1.addUser(new User(img[3], "杨幂", false, "其实我跟恺威已经离婚了,现在跟李易峰在一起,就酱~"));
Group group2 = new Group("超星星");
group2.addUser(new User(img[4], "林志炫", true, "其实我的小肚子都是唱歌导致的,哈哈哈"));
list.add(group1);
list.add(group2);
}
}
MainActivity.java
运行效果有点渣渣。请忽略:

Android ExpandableListView BaseExpandableListAdapter (类似QQ分组列表)的更多相关文章
- android开发之ExpandableListView的使用,实现类似QQ好友列表
由于工作需要,今天简单研究了一下ExpandableListView,做了一个类似QQ列表的Demo,和大家分享一下. 效果图如下: 先来看看主布局文件: <RelativeLayout xml ...
- android 网络广播 类似QQ动态检查网络
private ConnectivityManager mConnectivityManager; private NetworkInfo netInfo; 在onCreate 注册广播 Intent ...
- iOS 实现类似QQ分组样式的几种方式
思路 思路很简单,对模型数据操作或则控制界面显示 先看下json部分数据 "chapterDtoList": [{ "token": null, "i ...
- CSS+Jquery实现QQ分组列表
实现效果图如下: 说明: 1.css隐藏分组下的好友内容: 2.Jquery实现点击分组项事件,实现好友内容的显示和隐藏: 3.样式1,可展开多个分组:样式2,只能有一个分组展开: 源码: <! ...
- iOS UITableView制作类似QQ好友列表视图
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDele ...
- ExpandableListView仿QQ好友列表
本例中,对ExpandableListView中的数据进行了封装,分为两个JavaBean,一个为Group类表示组信息,一个Child类表示该组下子列表信息: Group: public class ...
- [iOS基础控件 - 6.9.3] QQ好友列表Demo TableView
A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组 code so ...
- swift 实现QQ好友列表功能
最近项目中有类似QQ好友列表功能,整理了一下,话不多说,直接上代码 import UIKit class QQFriend: NSObject { var name: String? var intr ...
- Android UI视图效果篇之仿QQ好友列表分组悬浮PinnedHeaderExpandableListView
楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeaderExpandableListView.java 要注意的是 在 onGroupClick方法中pare ...
随机推荐
- OpenGL ES 3.0 顶点缓冲区VBO使用
一般情况下数据都是有CPU从RAM取数据 然后传给GPU去处理,相对于GPU速度要慢一些. 使用VBO技术 可以把数据存储到GPU的内存空间中,这样GPU可以直接从GPU的内存中取得数据进行处理 速度 ...
- 删除重复记录的SQL语句
1.所有字段均重复的记录(重复记录保留一条) Select distinct * into #Tmp from tblName Drop table tblName Select * into tbl ...
- 《编写高质量代码--Web前端开发修炼之道》读书笔记
前言 这两周参加公司的新项目,采用封闭式开发(项目成员在会议室里开发),晚上加班到很晚,所以没时间和精力写原创博客了,今天就分享下这篇<编写高质量代码--Web前端开发修炼之道>读书笔记吧 ...
- zookeeper集群一次性启动
编写shell脚本 新建文本,命名为start-zookeeper.sh #!/bin/sh echo "start zkServer…" for i in master work ...
- underscorejs-reduceRight学习
2.4 reduceRight 2.4.1 语法: _.reduceRight(list, iteratee, memo, [context]) 2.3.2 说明: reduceRight和reduc ...
- ul ol 列表的样式的控制
ul( Unordered List)无序列表 ol(Ordered List)有序列表 列表的样式: 列表原有符号.自定义图形符号.符号显示位置. 1.列表符号 是显示于每一个列表项目前的符号标识. ...
- Dapper中使用存储分页。
#region 分页获取数据 /// <summary> /// 分页获取数据 /// </summary> /// <typeparam name="T&qu ...
- file upload download
1. 文件上传与下载 1.1 文件上传 案例: 注册表单/保存商品等相关模块! --à 注册选择头像 / 商品图片 (数据库:存储图片路径 / 图片保存到服务器中指定的目录) 文件上传,要点: 前台: ...
- $cordovaDialogs使用时遇到的问题
1:按照http://ngcordova.com/docs/plugins/dialogs/文档介绍进行安装使用: //标题栏 .controller('TitleCtrl', function($s ...
- PKUSC2016滚粗记
Day0 坐飞机来北京,地铁上接到电话,以为是诈骗电话马上就挂了,然后看了一下是北京的电话,赶脚有点不对...打回去居然是报到处老师的电话..走了几个小时,到勺园和其他学校的神犇合住.TAT,感觉第二 ...