在日常开发中,可能会遇到一些需要展开的列表,此时ListView已经不能满足使用了,今天来介绍ExpandableListView控件的使用。使用它可以很方便的做到二级列表,三级列表。ExpandableListview是ListView的子类,它在普通的ListView的基础上进行了扩展,它把应用中的列表分为几组,每组又包含了多个列表。
Demo中的数据我是拿取了省市区json字符串中的所有省,和每个省对应的市,只做了二级列表的效果,有兴趣的朋友可以在这个基础上增加到三级列表的效果
下面看一下Demo的运行效果
json数据格式为:
Demo的下载地址为:http://download.csdn.net/detail/shihuiyun/9567034 有需要的可以下载下来看看
主要代码如下:
//只用来展示省-市
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 解析省市区的json数据
initData();
}
// 解析json数据
private void initData() {
List<Map<String, String>> groups = new ArrayList<Map<String, String>>();
List<List<Map<String, String>>> childs = new ArrayList<List<Map<String, String>>>();
String jsondata = null;// 要解析的数据
StringBuffer sb = new StringBuffer();
try {
InputStream is = getAssets().open("city.json");
int len = -1;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
sb.append(new String(buf, 0, len, "utf-8"));
}
is.close();
jsondata = sb.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
JSONObject obj = new JSONObject(jsondata);
JSONArray arr = obj.getJSONArray("citylist");
Map<String, String> map;
List<Map<String, String>> list;
for (int i = 0; i < arr.length(); i++) {
JSONObject obj1 = arr.getJSONObject(i);
map = new HashMap<String, String>();
map.put("group", obj1.getString("p"));
JSONArray arr1 = obj1.getJSONArray("c");
Map<String, String> map1;
list = new ArrayList<Map<String, String>>();
for (int j = 0; j < arr1.length(); j++) {
JSONObject obj2 = arr1.getJSONObject(j);
map1 = new HashMap<String, String>();
map1.put("child", obj2.getString("n"));
list.add(map1);
}
childs.add(list);
groups.add(map);
}
ExpandableListView elv = (ExpandableListView) findViewById(R.id.mExpandableListView);
ExpandableAdapter viewAdapter = new ExpandableAdapter(this, groups,
childs);
elv.setAdapter(viewAdapter);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
自定义适配器ExpandableAdapter 的代码如下:
public class ExpandableAdapter extends BaseExpandableListAdapter
{
private Context context;
List<Map<String, String>> groups;
List<List<Map<String, String>>> childs;
/*
* 构造函数:
* 参数1:context对象
* 参数2:一级列表数据源
* 参数3:二级列表数据源
*/
public ExpandableAdapter(Context context, List<Map<String, String>> groups, List<List<Map<String, String>>> childs)
{
this.groups = groups;
this.childs = childs;
this.context = context;
}
public Object getChild(int groupPosition, int childPosition)
{
return childs.get(groupPosition).get(childPosition);
}
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
//获取二级列表的View对象
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent)
{
@SuppressWarnings("unchecked")
String text = ((Map<String, String>) getChild(groupPosition, childPosition)).get("child");
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//获取二级列表对应的布局文件, 并将其各元素设置相应的属性
LinearLayout linearLayout = (LinearLayout) layoutInflater.inflate(R.layout.childs, null);
TextView tv = (TextView) linearLayout.findViewById(R.id.child_tv);
tv.setText(text);
ImageView imageView = (ImageView)linearLayout.findViewById(R.id.child_iv);
imageView.setImageResource(R.drawable.icon);
return linearLayout;
}
public int getChildrenCount(int groupPosition)
{
int a;
try {
a=childs.get(groupPosition).size();
} catch (Exception e) {
a=0;
}
return a;
}
public Object getGroup(int groupPosition)
{
return groups.get(groupPosition);
}
public int getGroupCount()
{
return groups.size();
}
public long getGroupId(int groupPosition)
{
return groupPosition;
}
//获取一级列表View对象
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
String text = groups.get(groupPosition).get("group");
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//获取一级列表布局文件,设置相应元素属性
LinearLayout linearLayout = (LinearLayout) layoutInflater.inflate(R.layout.group, null);
TextView textView = (TextView)linearLayout.findViewById(R.id.group_tv);
textView.setText(text);
ImageView imageView = (ImageView) linearLayout.findViewById(R.id.mImageView);
if(getChildrenCount(groupPosition) == 0){//该组下没有子项
//imageView.setVisibility(View.GONE);
imageView.setImageResource(R.drawable.down);
}else{
if(isExpanded == true){//展开状态
imageView.setImageResource(R.drawable.down);
}else{//收起状态
imageView.setImageResource(R.drawable.on);
}
}
return linearLayout;
}
public boolean hasStableIds()
{
return false;
}
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return false;
}
}
几个布局文件如下:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 禁用系统自带图标android:groupIndicator="@null" -->
<ExpandableListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:groupIndicator="@null"
android:id="@+id/mExpandableListView"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
</LinearLayout>
group.xml
<?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" >
<ImageView
android:id="@+id/mImageView"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/group_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:gravity="center_vertical|left"
android:textColor="#000000"
android:textSize="26sp" />
</LinearLayout>
childs.xml
<?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="vertical" >
<ImageView
android:id="@+id/child_iv"
android:layout_width="1dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginBottom="2dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="2dp"
android:scaleType="fitXY"
android:src="@drawable/icon" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:orientation="horizontal" >
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical|left"
android:scaleType="fitXY"
android:src="@drawable/to" />
<TextView
android:id="@+id/child_tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
这样就实现了简单是二级列表,图片与文字的距离你可以自己设定