前言

眼下回到了工作岗位,第一件事情就是ExpandListView的优化。这里简单的用一个Demo介绍一下ExpandableListView的使用。

简介一下Demo实现的功能,主要是继承BaseExpandableListAdapter来自己定义adapter呈现ExpandableListView数据:
  • 每一个child item有一个TextView和一个ImageView删除标识。
  • 当点击一个child item,弹出Toast提示。
  • child item能够通过点击删除图标来删除。

  • 每次展开特定group时。其它group自己主动收缩。

Demo效果展示:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3p5XzE5ODg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">



Android实现

创建一个新的Android项目,我将其命名为expandtutorial。

XML布局文件

expandtutorial项目总共须要三个xml布局文件。各自是activity_main.xml。 child_item.xml。 group_item.xml。

activity_main.xml

这个是用来布局ExpandableListView的,内容例如以下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" > <ExpandableListView
android:id="@+id/expandable_list_view_id"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ExpandableListView> </RelativeLayout>

group_item.xml

这是用来定义父列表的样式,由一个TextView和一个ImageView构成

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#ffffff"
android:orientation="horizontal"
android:gravity="center_vertical"> <TextView
android:id="@+id/group_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:textColor="#808080"
android:textSize="16sp"
android:gravity="center_vertical"
android:layout_alignParentLeft="true"
android:text="@string/app_name"/> <ImageView
android:id="@+id/group_indicator"
android:src="@drawable/ic_guide_listview_down"
android:contentDescription="@null"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="16sp"
android:layout_alignParentRight="true"/> </RelativeLayout>

child_item.xml

这是用来定义孩子列表的样式

<?

xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/child_item_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp" > <TextView
android:id="@+id/child_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:paddingLeft="25dp" /> <ImageView
android:id="@+id/child_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:contentDescription="@null"
android:src="@drawable/delete" /> </RelativeLayout>

自己定义Adapter

自己定义adapter是继承自BaseExpandableListAdapter。有几个须要注意的地方:
  • 使用静态内部类标识父item和子item的weidget,由于这些控件的id是同样的,这样能够节省掉每次findViewById的时间。
  • 重写(override)isChildSelectable方法,返回true,表示子item是能够点击的。
package com.example.expandtutorial;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView; public class CustomerAdapter extends BaseExpandableListAdapter{
private ArrayList<ParentObj> datas;
private Context context; public CustomerAdapter(ArrayList<ParentObj> datas, Context context) {
super();
this.datas = datas;
this.context = context;
} @Override
public int getGroupCount() {
return datas.size();
} @Override
public int getChildrenCount(int groupPosition) {
return datas.get(groupPosition).getChilds().size();
} @Override
public Object getGroup(int groupPosition) {
return datas.get(groupPosition);
} @Override
public Object getChild(int groupPosition, int childPosition) {
return datas.get(groupPosition).getChilds().get(childPosition);
} @Override
public long getGroupId(int groupPosition) {
return groupPosition;
} @Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
} @Override
// 是否有稳定的id。跟刷新顺序有关
public boolean hasStableIds() {
return false;
} @Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ParentViewHolder pviewHolder; if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.group_item, parent, false);
pviewHolder = new ParentViewHolder();
pviewHolder.pTextView = (TextView) convertView.findViewById(R.id.group_text);
pviewHolder.pImageView = (ImageView) convertView.findViewById(R.id.group_indicator);
convertView.setTag(pviewHolder);
} pviewHolder = (ParentViewHolder)convertView.getTag();
pviewHolder.pTextView.setTypeface(null, Typeface.BOLD);
pviewHolder.pTextView.setText(datas.get(groupPosition).getpName()); if (isExpanded) {
pviewHolder.pImageView.setImageResource(R.drawable.ic_guide_listview_up);
} else {
pviewHolder.pImageView.setImageResource(R.drawable.ic_guide_listview_down);
} return convertView;
} @Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
ChildViewHolder cViewHolder; if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.child_item, parent, false);
cViewHolder = new ChildViewHolder();
cViewHolder.cTextView = (TextView)convertView.findViewById(R.id.child_item);
cViewHolder.cImageView = (ImageView) convertView.findViewById(R.id.child_delete);
convertView.setTag(cViewHolder);
} cViewHolder = (ChildViewHolder)convertView.getTag();
cViewHolder.cTextView.setText(datas.get(groupPosition).getChilds().get(childPosition).getcName()); final int gPosition = groupPosition;
final int cPosition = childPosition;
cViewHolder.cImageView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Do you want to remove?");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
datas.get(gPosition).getChilds().remove(cPosition);
notifyDataSetChanged();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}); return convertView;
} @Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
} static class ParentViewHolder {
TextView pTextView;
ImageView pImageView;
} static class ChildViewHolder {
TextView cTextView;
ImageView cImageView;
}
}

Activity

我们的主Activity,用来呈现UI效果,这里主要有两个地方须要注意:
  • ExpandableListView须要和自己定义adapter进行绑定,通过setAdapter方法。

  • 默认ExpandableListView带了一个指示箭头。我们自己定义布局是不须要这个指示箭头的。能够使用expandableListView.setGroupIndicator(null);方法将其去掉。
  • 设置setOnGroupExpandListener,当展开一个特定的group时,关闭其它group。
  • 设置setOnChildClickListener,监听孩子点击事件。
package com.example.expandtutorial;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.Toast; public class MainActivity extends Activity {
private ExpandableListView expandableListView;
private CustomerAdapter customerAdapter;
private ArrayList<ParentObj> listData = new ArrayList<ParentObj>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); createGroupData(); createChildData(); expandableListView = (ExpandableListView) findViewById(R.id.expandable_list_view_id);
customerAdapter = new CustomerAdapter(listData, this);
expandableListView.setAdapter(customerAdapter);
expandableListView.setGroupIndicator(null); expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() { @Override
public void onGroupExpand(int groupPosition) {
for (int i = 0; i < customerAdapter.getGroupCount(); i ++) {
if (i != groupPosition) {
expandableListView.collapseGroup(i);
}
}
}
}); expandableListView.setOnChildClickListener(new OnChildClickListener() { @Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(MainActivity.this, listData.get(groupPosition).getChilds().get(childPosition).getcName(), Toast.LENGTH_LONG).show();
return true;
}
});
} private void createGroupData() {
ParentObj p1 = new ParentObj();
p1.setpName("HP");
listData.add(p1); ParentObj p2 = new ParentObj();
p2.setpName("DELL");
listData.add(p2); ParentObj p3 = new ParentObj();
p3.setpName("Lenovo");
listData.add(p3); ParentObj p4 = new ParentObj();
p4.setpName("Sony");
listData.add(p4); ParentObj p5 = new ParentObj();
p5.setpName("HCL");
listData.add(p5); ParentObj p6 = new ParentObj();
p6.setpName("Samsung");
listData.add(p6);
} private void createChildData() {
// preparing laptops collection(child)
String[] hpModels = { "HP Pavilion G6-2014TX", "ProBook HP 4540", "HP Envy 4-1025TX" };
String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" };
String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series", "ThinkPad X Series", "Ideapad Z Series" };
String[] sonyModels = { "VAIO E Series", "VAIO Z Series", "VAIO S Series", "VAIO YB Series" };
String[] dellModels = { "Inspiron", "Vostro", "XPS" };
String[] samsungModels = { "NP Series", "Series 5", "SF Series" }; for (ParentObj p : listData) {
if (p.getpName().equals("HP")) {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < hpModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(hpModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
} else if (p.getpName().equals("DELL")) {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < dellModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(dellModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
} else if (p.getpName().equals("Lenovo")) {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < lenovoModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(lenovoModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
} else if (p.getpName().equals("Sony")) {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < sonyModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(sonyModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
} else if (p.getpName().equals("HCL")) {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < hclModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(hclModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
} else {
ArrayList<ChildObj> clists = new ArrayList<ChildObj>();
for (int i = 0; i < samsungModels.length; i ++) {
ChildObj cObj = new ChildObj();
cObj.setcName(samsungModels[i]);
clists.add(cObj);
}
p.setChilds(clists);
}
}
}
} class ParentObj {
private String pName;
private ArrayList<ChildObj> childs = new ArrayList<ChildObj>(); public String getpName() {
return pName;
} public void setpName(String pName) {
this.pName = pName;
} public ArrayList<ChildObj> getChilds() {
return childs;
} public void setChilds(ArrayList<ChildObj> childs) {
this.childs.clear();
this.childs.addAll(childs);
}
} class ChildObj {
private String cName; public String getcName() {
return cName;
} public void setcName(String cName) {
this.cName = cName;
}
}

源代码

我将源代码上传到CSDN,大家能够免费下载,欢迎跟帖讨论。源代码地址:http://download.csdn.net/detail/zinss26914/7532205



Android:ExpandableListView使用的更多相关文章

  1. 【开源项目4】Android ExpandableListView

    如果你对Android提供的Android ExpandableListView并不满意,一心想要实现诸如Spotify应用那般的效果,那么SlideExpandableListView绝对是你最好的 ...

  2. 【原创】Android ExpandableListView使用

    ExpandableView的使用可以绑定到SimpleExpandableListAdapter,主要是看这个Adapter怎么用. 这个类默认的构造函数有9个参数, 很好地解释了什么叫做又臭又长. ...

  3. Android ExpandableListView

    ExpandableListView 结合SimpleExpandableListAdapter用法 最终实现效果: activity_main.xml <?xml version=" ...

  4. android ExpandableListView详解

    ExpandableListView是android中可以实现下拉list的一个控件,是一个垂直滚动的心事两个级别列表项手风琴试图,列表项是来自ExpandableListViewaAdapter,组 ...

  5. 解决android expandablelistview 里面嵌入gridview行数据重复问题

    最近做了一个“csdn专家博客App” 当然了是android版本,在专家浏览页面,我才用了expandablelistview 组件来显示专家分类,每个分类点击之后可以显示专家的头像和名字. 很简单 ...

  6. Android ExpandableListView的下拉刷新实现

    该控件的修改时根据PullToRefreshList的机制修改 下面是对ExpandableListView的扩展 package com.up91.gwy.view.componet; import ...

  7. Android ExpandableListView的技巧和问题

    前言: 最近一个多月在认真的学习Android和做项目,文章内容表达的不好或者理解错了,希望大家评论指出. :-) 本文是总结几个比较常用且使用的技巧,和一个大家都会遇到的问题. 文章中大部分语句摘抄 ...

  8. Android ExpandableListView 带有Checkbox的简单应用

    expandablelistview2_groups.xml <?xml version="1.0" encoding="utf-8"?> < ...

  9. Android ExpandableListView的简单应用

    Expandablelistview1Activity.java package com.wangzhu.demoexpandablelistview; import java.util.ArrayL ...

  10. Android ExpandableListView使用+获取SIM卡状态信息

    ExpandableListView 是一个可以实现下拉列表的控件,大家可能都用过QQ,QQ中的好友列表就是用ExpandableListView实现的,不过它是自定义的适配器.本篇 博客除了要介绍E ...

随机推荐

  1. PCB Windows远程桌面一键登录

    开发时会经常需远程操作服务器,每次运行再也熟悉不过的命令 mstsc 或 mstsc -v  120.79.36.65 远程到目标服务器, 每次需输入密码,弹出烦人的 如何免密码一键登录呢,其实微软已 ...

  2. Appium + python - get_attribute获取value操作

    from appium import webdriverfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.w ...

  3. php函数 array_values()

    array_values() 函数返回一个包含给定数组中所有键值的数组,但不保留键名. 提示:被返回的数组将使用数值键,从 0 开始并以 1 递增. $a=array("Name" ...

  4. 前端布局神器 display:flex

    前端布局神器display:flex 一直使用flex布局,屡试不爽,但是总是记不住一些属性,这里写来记录一下.   2009年,W3C提出了一种新的方案--Flex布局,可以简便.完整.响应式地实现 ...

  5. oracle命令行登录(默认用户名和密码)

    oracle数据库安装成功之后会有默认的用户名和密码,之前因为没有整理,每次用的时候都要百度很麻烦,所以现在把这些都整理一下,也方便以后使用: 使用scott用户连接:使用sys用户连接:使用syst ...

  6. Android开放百度地图集成

    1.创建应用 获取AK (我理解为Application key)  通过百度账号登录百度地图开放平台,进入API控制台 http://lbsyun.baidu.com/apiconsole/key ...

  7. 能够附加图片的标签控件iOS项目源码

    这个源码案例是能够附加图片的标签控件,源码JTImageLabel,JTImageLabel能够附加图片的标签Label控件,图片可以随意更换.位置也能够很好的控制.效果图: <ignore_j ...

  8. CorelDRAW图片导出变色,如何解决?

    很多小伙伴反映说CDR颜色导出不准确,特别是CorelDRAW X4以及之前的版本,那么CDR导出变色的问题是怎么导致的,如何解决呢,本文小编分享一些自己的心得. 一:出现问题. 比如下面这个问题,明 ...

  9. Lua操作系统库、流、文件库

    Lua操作系统库.流.文件库 1.Lua中所有的操作系统库函数 (1)os.clock() --功能:返回执行该程序cpu花费的时钟秒数 (2)os.time(...) --按参数的内容返回一个时间值 ...

  10. [Usaco2004 Open]Cube Stacking 方块游戏

    题面:     约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.    游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种 ...