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. //取得显示给定分组给定子位置的数据用的视图。
2. public abstract View getChildView (int groupPosition, intchildPosition
, boolean isLastChild, ViewconvertView, ViewGroup parent){
3. //groupPosition 包含要取得子视图的分组位置。
4. //childPosition 分组中子视图(要返回的视图)的位置。
5. //isLastChild 该视图是否为组中的最后一个视图。
6. //convertView 如果可能,重用旧的视图对象,使用前你应该保证视图对象为非
空,并且是否是合适的类型,如果该对象不能转换为可以正确显示数据的视图,该方法就创建新
视图.不保证使用先前由getChildView(int, int,boolean, View, ViewGroup)创建的
视图.
7. //parent 该视图最终从属的父视图.
8. 返回 指定位置相应的子视图.
9. }
10.
11. //取得指定分组的子元素数。
12. public abstract int getChildrenCount (int groupPosition){
13. //groupPosition 要取得子元素个数的分组位置。
14. 返回 指定分组的子元素个数.
15. }
16.
17. //取得用于显示给定分组的视图.这个方法仅返回分组的视图对象,要想获取子元素的视图对象
,就需要调用getChildView(int, int, boolean, View, ViewGroup)。
18. public abstract View getGroupView (int groupPosition,
booleanisExpanded, View convertView, ViewGroupparent){
19. //groupPosition 决定返回哪个视图的组位置.
20. //isExpanded 该组是展开状态还是收起状态 .
21. //convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,
并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.
不保证使用先前由getGroupView(int, boolean,View, ViewGroup)创建的视图.
22. //parent 该视图最终从属的父视图.
23. 返回 指定位置相应的组视图.
24. }
25.
26. //取得分组数。
27. public abstract int getGroupCount (){
28. 返回 分组数。
29. }

注意:在XML布局文件中,如果ExpandableListView上一级视图的大小没有严格定义的话,则不能对ExpandableListView的android:layout_height属性使用wrap_content值。(例如,如果上一级视图是ScrollView的话,则不应该指定wrap_content的值,因为它可以是任意的长度。不过,如果ExpandableListView的上一级视图有特定的大小的话,比如100像素,则可以使用wrap_content)

示例图如下:

//Activity类

public class MainActivity extends Activity {List<Group> mlist=new ArrayList<Group>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intiData();ExpandableListView el=(ExpandableListView) findViewById(R.id.el);FriendAdapter adapter = new FriendAdapter(this, mlist);el.setAdapter(adapter);}private void intiData() {// 创建一些数据来测试Group group1 = new Group();User user1 = new User(R.drawable.p01, "蝴蝶", true, "假如此刻还有许些的难过,也许是美丽夜色伤感了我");User user2 = new User(R.drawable.p02, "牡丹", true, "天长和地久若只是个传说,何必去追问谁对谁错");User user3 = new User(R.drawable.p03, "杜鹃", false, "曾以为得到的就是快乐,筋疲力尽还要彼此折磨");User user4 = new User(R.drawable.p04, "兰花", true, "海誓和山盟变成了泡沫,难道只有放弃才能解脱");group1.addUser(user1);group1.addUser(user2);group1.addUser(user3);group1.addUser(user4);group1.name = "小学同学";Group group2 = new Group();User user5 = new User(R.drawable.p05jpg, "芍药", false, "为什么付出那么多,你还是让我感到悲伤难过");User user7 = new User(R.drawable.p07, "柔儿", true, "为什么付出那么多,竟然却越来越感到了迷惑");group2.addUser(user5);group2.addUser(user7);group2.name = "陌生人";Group group3 = new Group();User user6 = new User(R.drawable.p06, "美女", true, "是我自己太过的软弱,还是上辈子欠你的太多");group3.addUser(user6);group3.name = "爱人";mlist.add(group1);mlist.add(group2);mlist.add(group3);}}

//自己写的Adapter类

public class FriendAdapter extends BaseExpandableListAdapter {private Context context;private List<Group> mlist;public FriendAdapter(Context context, List<Group> list) {this.context = context;this.mlist = list;}@Overridepublic int getGroupCount() {return mlist.size();}@Overridepublic int getChildrenCount(int groupPosition) {return mlist.get(groupPosition).size();}@Overridepublic Group getGroup(int groupPosition) {return mlist.get(groupPosition);}@Overridepublic User getChild(int groupPosition, int childPosition) {return mlist.get(groupPosition).list.get(childPosition);}@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}@Overridepublic boolean hasStableIds() {return true;}@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {GroupHolder holder;if (convertView == null) {convertView = View.inflate(context, R.layout.group_activity, null);holder = new GroupHolder(convertView);convertView.setTag(holder);}holder = (GroupHolder) convertView.getTag();Group group = getGroup(groupPosition);holder.name.setText(group.name);holder.online.setText(group.getCount() + "/" + group.size());return convertView;}@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {ChildHolder holder;if (convertView == null) {convertView = View.inflate(context, R.layout.user_activity, null);holder = new ChildHolder(convertView);convertView.setTag(holder);}holder = (ChildHolder) convertView.getTag();User user = mlist.get(groupPosition).list.get(childPosition);holder.img.setImageResource(user.getImgid());holder.name.setText(user.getName());holder.online.setText(user.isOnline ? "[在线]" : "[离线]");holder.sign.setText(user.getSign());return convertView;}@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return true;}class GroupHolder {TextView name, online;public GroupHolder(View convertView) {name = (TextView) convertView.findViewById(R.id.group_name);online = (TextView) convertView.findViewById(R.id.group_online);}}class ChildHolder {ImageView img;TextView name, online, sign;public ChildHolder(View convertView) {name = (TextView) convertView.findViewById(R.id.user_name);online = (TextView) convertView.findViewById(R.id.user_online);sign = (TextView) convertView.findViewById(R.id.user_sign);img = (ImageView) convertView.findViewById(R.id.user_img);}}}

//第一个布局类 也就是分组类

public class Group {List<User> list = new ArrayList<User>();String name;public int size() {return list.size();}public void addUser(User user) {list.add(user);}public int  getCount() {int sum=0;for (User user : list) {if (user.isOnline) {sum++;}}return sum;}
}

//第二个布局类 也就是一个分组类中存在的元素类

ublic class User {int imgid;String name;boolean isOnline;String sign;public User() {super();}public User(int imgid, String name, boolean isOnline, String sign) {super();this.imgid = imgid;this.name = name;this.isOnline = isOnline;this.sign = sign;}@Overridepublic String toString() {return "User [imgid=" + imgid + ", name=" + name + ", isOnline="+ isOnline + ", sign=" + sign + "]";}public int getImgid() {return imgid;}public void setImgid(int imgid) {this.imgid = imgid;}public String getName() {return name;}public void setName(String name) {this.name = name;}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;}}

//把图像变成圆形的类

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;}@Overrideprotected 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;}}//需要在values中建立一个为circle_attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="CircularImage"><attr name="border_width" format="dimension" /><attr name="border_color" format="color" /></declare-styleable></resources>

//主布局

<RelativeLayout 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"tools:context="com.xykj.id05_10_12work7_4.MainActivity" ><ExpandableListView android:id="@+id/el"android:layout_width="wrap_content"android:layout_height="wrap_content"></ExpandableListView></RelativeLayout>

//第一个布局也就是分组的那个布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="20dp" ><TextView
        android:id="@+id/group_name"android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="组名"/><TextView android:id="@+id/group_online"android:layout_alignParentRight="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="1/3"/></RelativeLayout>

//第二个布局也就是分组里面显示的布局

<?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="match_parent"android:orientation="horizontal" ><com.xykj.id05_10_12work7_4.CircleImageView android:layout_width="80dp"android:layout_height="80dp"android:id="@+id/user_img"android:src="@drawable/ic_launcher"/><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"><TextView android:id="@+id/user_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="名称"android:textSize="18sp"/><LinearLayout android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"><TextView
                android:id="@+id/user_online"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="[在线]"android:textStyle="bold" /><TextView
                android:id="@+id/user_sign"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="签名" /></LinearLayout></LinearLayout></LinearLayout>

ImageSwitcher图像切换器

图像切换器使用ImageSwitcher表示,用于实现类似于windows操作系统下的”Windows照片
查询器”中的上一张,下一张切换图片的功能,在使用ImageSwitcher时,必须实现ViewSwitcher.ViewFactory接口,并通过makeView()方法来创建用于显示图片的ImageView
makeView()方法将返回一个显示图片的ImageView.在使用图像切换器时,还有一个方法非常
重要,那就是setImageResource()方法,该方法用于指定要在ImageSwitcher中显示的图片资源.

视图如下图:

package com.example.lesson7_imageswitcher;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;public class MainActivity extends Activity {int[] resId = { R.drawable.img01, R.drawable.img02, R.drawable.img03,R.drawable.img04, R.drawable.img05, R.drawable.img06 };int index = 0;ImageSwitcher is;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);is = (ImageSwitcher) findViewById(R.id.is);is.setFactory(new ViewFactory() {// 用什么View来展示@Overridepublic View makeView() {ImageView iv = new ImageView(getBaseContext());return iv;}});is.setImageResource(resId[index]);}public void up(View v) {index--;if (index < 0)index = resId.length - 1;is.setImageResource(resId[index]);}public void down(View v) {index++;if (index == resId.length)index = 0;is.setImageResource(resId[index]);}}
<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="horizontal"tools:context="com.example.lesson7_imageswitcher.MainActivity" ><Button
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="up"android:text="上一张" /><ImageSwitcher
        android:id="@+id/is"android:layout_width="wrap_content"android:layout_height="wrap_content" ></ImageSwitcher><Button
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="down"android:text="下一张" /></LinearLayout>

Gallery画廊视图(已过期,还能用)

画廊视图使用Gallery表示,能够按水平方向显示内容,并且可以手指直接拖动图片和移动,一般用
来浏览图片,,被选中的选项位于中间,并且可以响应事件显示信息.在使用画廊视图时,首先在屏幕
上添加Gallery组件,通常使用标记在XML而布局文件中添加.
画廊视图在4.0后已经过期,但是我们仍然可以使用,不过后面我们将用水平的ListView
自定义组件来实现这个效果,在自定义视图中讲解。

常用属性:
1. android:animationDuration 用于设置列表项切换时的动画持续时间
2. android:gravity 用于设置对齐方式
3. android:spacing 用于设置列表项之间的间距
4. android:unselectedAlpha 用于设置没有选中的列表项的透明度

示例图如下:

public class MainActivity extends Activity {//RecyleViewGallery gl;int[] resId = { R.drawable.img01, R.drawable.img02, R.drawable.img03,R.drawable.img04, R.drawable.img05, R.drawable.img06 };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);gl = (Gallery) findViewById(R.id.gl);gl.setAdapter(adapter);gl.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent, View view,int position, long id) {Log.e("TAG", "--" + position + "被选中");}@Overridepublic void onNothingSelected(AdapterView<?> parent) {// TODO Auto-generated method stub}});}private BaseAdapter adapter = new BaseAdapter() {@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null)convertView = new ImageView(MainActivity.this);ImageView iv = (ImageView) convertView;iv.setPadding(20, 20, 20, 20);iv.setImageResource(resId[position]);return convertView;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic int getCount() {return resId.length;}};
}
<RelativeLayout 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"tools:context="com.example.lesson7_gallery.MainActivity" ><Gallery
        android:id="@+id/gl"android:layout_width="match_parent"android:layout_height="wrap_content" /></RelativeLayout>

android中的高级组件(三)(ExpandableListView,ImageSwitcher,Gallery)相关推荐

  1. Android学习——UI高级组件三

    Android学习--UI高级组件三 PopupWindow(弹出式窗口) Android的对话框有两种:PopupWindow和AlertDialog.它们的不同点在于:AlertDialog位置固 ...

  2. android 界面组件,安卓开发学习周第三篇——Android中的UI组件

    原标题:安卓开发学习周第三篇--Android中的UI组件 在Android APP中,所有的用户界面元素都是由View和ViewGroup的对象构成的.View是绘制在屏幕上的用户能与之交互的一个对 ...

  3. Android常见的高级组件搭建移动应用界面

    Android常见的高级组件结合可以搭建移动应用常见的界面结构,如下图所示: 上述的界面可以发现有侧滑菜单,界面的主内容区顶部可以显示Home键.应用标题以及菜单.在底部有导航栏方便导航.通过侧滑菜单 ...

  4. Android中的四大组件详解

    Android中的四大组件详解 我们都知道Android系统应用层框架中,为开发者提供了四大组件来便于应用的开发,它们是Activity.Service.BroadcastReceiver.Conte ...

  5. 寻找android中的设计模式(三)

     寻找android中的设计模式(三) 寻找工厂模式 工厂模式的家族分四种:静态工厂模式.简单工厂模式.工厂方法模式.抽象工厂模式. 下面以开冒菜店为例,假设我定义了一家冒菜店: <pre ...

  6. Android中所有UI组件基类是,【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity...

    问:达叔,你放弃了吗? 答:不,放弃是不可能的,丢了Android,你会心疼吗?如果别人把你丢掉,你是痛苦呢?还是痛苦呢?~ 引导语 有人说,爱上一个人是痛苦的,有人说,喜欢一个人是幸福的. 人与人之 ...

  7. Android中获取网络图片的三种方法

    android中获取网络图片是一件耗时的操作,如果直接获取有可能会出现应用程序无响应(ANR:Application Not Responding)对话框的情况.对于这种情况,一般的方法就是耗时操作用 ...

  8. Android中夜间模式的三种实现方式

    参考:https://www.jianshu.com/p/f3aaed57fa15 在本篇文章中给出了三种实现日间/夜间模式切换的方案: 使用 setTheme 的方法让 Activity 重新设置主 ...

  9. Android中图片圆形设置三种方法介绍

    Android开发中经常会用到圆形图片,比如在用户头像设置,现在提供三种主要实现方式: 方案一:使用第三方图像框架 Fresco 1.添加依赖 dependencies {compile 'com.f ...

最新文章

  1. hadoop源码datanode序列图
  2. 网红 AI 高仿坎爷发布说唱情歌,歌迷:堪比真人原声
  3. mysql 数据库编译安装_mysql 数据库 编译安装(千峰)
  4. OpenCV形态学变换函数morphologyEx()黑帽运算的使用
  5. ajax div 赋值重新渲染_30分钟全面解析图解AJAX原理
  6. 使用eclipse调试ns3配置说明
  7. NameError: name 'random' is not defined
  8. C语言程序设计教程(第三版)课后习题6.3
  9. 一个简单的划词翻译工具
  10. 2021年第十八届五一数学建模竞赛题目 C题 数据驱动的异常检测与预警问题 解题论文完整版
  11. 不开机win7计算机还原,Win7开机出现Windows错误恢复解决方法
  12. 吉哥系列故事——礼尚往来
  13. java根据出生日期计算年龄_通过出生日期获取年龄的方法--Java
  14. UE4----GC(垃圾回收)
  15. 一位外包女程序员的心酸史和无奈
  16. 会心自选-淘宝店铺装修和转化率的关系
  17. 如何构建超现实元宇宙空间
  18. 基于神经网络的颜色恒常性—Fully Convolutional Color Constancy with Confidence-weighted Pooling
  19. Exiting on user cancel解决
  20. 地鼠宝宝的轶事奇闻之线程模型

热门文章

  1. 临时记录一次ic卡破解(1)
  2. .7z.001,.7z.002这样的文件如何解压
  3. 2023年全国最新工会考试精选真题及答案47
  4. 2023年全国最新工会考试精选真题及答案10
  5. 大屏互动-大屏交互-大屏投影技术解决方案
  6. C语言学习:除去剪切板内容的换行与回车
  7. Web前端面试常用技巧
  8. laravel entrust 权限管理
  9. js两种滚动事件写法
  10. 计算机毕业设计Java物流信息管理系统录像演示(源码+系统+mysql数据库+Lw文档)