分组列表视图(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 ...
随机推荐
-
win7(64)位下WinDbg64调试VMware10下的win7(32位)
win7(64)位下WinDbg64调试VMware10下的win7(32位) 一 Windbg32位还是64位的选择 参考文档<Windbg 32位版本和64位版本的选择> http:/ ...
-
SOA体系结构之基础培训教程-大纲篇
引言: 最近受邀做了一个企业的SOA体系结构的内训,本文是内训课程的培训大纲,分享一下吧,希望大家能够喜欢.同时也想针对大纲中列出的内容对SOA架构体系做一次回顾,如果时间允许把完整的课件也想放上来共 ...
-
数据库Schema两种含义~~
1.数据库Schema有两种含义,一种是概念上的Schema,指的是一组DDL语句集,该语句集完整地描述了数据库的结构.还有一种是物理上的 Schema,指的是数据库中的一个名字空间,它包含一组表.视 ...
-
centos 7 开机yum
yum -y install net-tools yum -y install wget
-
Eclipse中Maven的简单使用
一.Maven的安装 检查自己的电脑是否安装了maven,在cmd中输入 mvn -v 命令即可查看 安装配置maven 1.解压部署Maven核心程序 ①检查JAVA_HOME环境变量 C:\Wi ...
-
vue-cli+webpack项目,修改项目名称
使用vue-cli+webpack创建的项目,修改文件名称或者更改文件的位置,运营时会报错,是因为npm项目,在安装依赖(node_nodules)时,会记录当前的文件路径,当修改之后就无法正常启动. ...
-
Java Collection集合方法
一.简单方法 package cn.itcast.day15; import java.util.ArrayList; import java.util.Arrays; import java.uti ...
-
【QT】QML的Mouse事件(MouseArea)详解
https://blog.csdn.net/ieearth/article/details/42082837
-
JAVA 使用Comparator接口实现自定义排序
1.原则 Comparator接口可以实现自定义排序,实现Comparator接口时,要重写compare方法: int compare(Object o1, Object o2) 返回一个基本类型的 ...
-
java中十进制转换为任意进制
次笔试时候遇到的关于十进制转换成十三进制的编程题. 先说说简单的思路吧: 1.十进制数 num 转换为 n进制 num%n结果肯定为n进制数的最后一位 结果存入一个数组中 2.进入一个循环num!=0 ...