某些android開發羣裏,看到有些新手問怎麼實現QQ好友列表,其實網上一搜挺多的。接觸Android,也才一年的時間,大部分時間花在工做上(解bug。。。),界面上開發不多參與。本身維護的系統應用裏,有個ExpandableListView的界面(其實android例子APIDemo也有相似的例子)就在這裏寫個Demo供新手參考。 html
ExpandableListView的用法:難點就是重寫BaseExpandableListAdapter及提供的數據源。 java
下面看看繼承BaseExpandableListAdapter的適配器: android
[java]
<span xmlns="http://www.w3.org/1999/xhtml" style="">package com.xyz.expande;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ExpandAdapter extends BaseExpandableListAdapter {
private Context mContext;
private LayoutInflater mInflater = null;
private String[] mGroupStrings = null;
private List<List<Item>> mData = null;
public ExpandAdapter(Context ctx, List<List<Item>> list) {
mContext = ctx;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mGroupStrings = mContext.getResources().getStringArray(R.array.groups);
mData = list;
}
public void setData(List<List<Item>> list) {
mData = list;
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition).size();
}
@Override
public List<Item> getGroup(int groupPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition);
}
@Override
public Item getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return mData.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = mInflater.inflate(R.layout.group_item_layout, null);
}
GroupViewHolder holder = new GroupViewHolder();
holder.mGroupName = (TextView) convertView
.findViewById(R.id.group_name);
holder.mGroupName.setText(mGroupStrings[groupPosition]);
holder.mGroupCount = (TextView) convertView
.findViewById(R.id.group_count);
holder.mGroupCount.setText("[" + mData.get(groupPosition).size() + "]");
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = mInflater.inflate(R.layout.child_item_layout, null);
}
ChildViewHolder holder = new ChildViewHolder();
holder.mIcon = (ImageView) convertView.findViewById(R.id.img);
holder.mIcon.setBackgroundResource(getChild(groupPosition,
childPosition).getImageId());
holder.mChildName = (TextView) convertView.findViewById(R.id.item_name);
holder.mChildName.setText(getChild(groupPosition, childPosition)
.getName());
holder.mDetail = (TextView) convertView.findViewById(R.id.item_detail);
holder.mDetail.setText(getChild(groupPosition, childPosition)
.getDetail());
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
<span style="color:#cc0000;">/*很重要:實現ChildView點擊事件,必須返回true*/
</span> return true;
}
private class GroupViewHolder {
TextView mGroupName;
TextView mGroupCount;
}
private class ChildViewHolder {
ImageView mIcon;
TextView mChildName;
TextView mDetail;
}
}
</span>
裏面用到的有兩個佈局,GroupView(子list沒展開的view)如圖:
佈局group_item_layout.xml以下: app
[java]
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><?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="?android:attr/listPreferredItemHeight"
android:orientation="horizontal" >
<TextView
android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="?android:attr/listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="35dip"
android:gravity="center_vertical"
android:singleLine="true" />
<TextView
android:id="@+id/group_count"
android:layout_width="wrap_content"
android:layout_height="?android:attr/listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="5dip"
android:gravity="center_vertical"
android:singleLine="true"/>
</LinearLayout></span></span> ide
另一個就是ChildView,本例仿QQ好友列表,如圖: 佈局
哈哈,熟悉吧。佈局child_item_layout.xml以下: ui
[java]
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/min_Height"
<span style="color:#ff0000;">android:descendantFocusability="blocksDescendants"
</span> android:orientation="horizontal" >
<ImageButton
android:id="@+id/img"
android:layout_width="@dimen/image_width"
android:layout_height="@dimen/image_width"
android:layout_marginLeft="2dip"
android:layout_marginRight="10dip"
android:layout_gravity="center_vertical" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="0.0dip"
android:gravity="center_vertical"
android:layout_weight="1" />
<TextView
android:id="@+id/item_detail"
android:layout_width="wrap_content"
android:layout_height="0.0dip"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout></span></span>
適配器弄好了,ExpandableListView就用系統的,如今只剩下顯示的問題啦
先來幾張效果圖: this
主Activity以下: spa
onChildClick xml
[java]
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style="">package com.xyz.expande;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
public class HomeActivity extends Activity implements OnChildClickListener {
private ExpandableListView mListView = null;
private ExpandAdapter mAdapter = null;
private List<List<Item>> mData = new ArrayList<List<Item>>();
private int[] mGroupArrays = new int[] {
R.array.tianlongbabu,
R.array.shediaoyingxiongzhuan,
R.array.shendiaoxialv };
private int[] mDetailIds = new int[] {
R.array.tianlongbabu_detail,
R.array.shediaoyingxiongzhuan_detail,
R.array.shendiaoxialv_detail };
private int[][] mImageIds = new int[][] {
{ R.drawable.img_00,
R.drawable.img_01,
R.drawable.img_02 },
{ R.drawable.img_10,
R.drawable.img_11,
R.drawable.img_12,
R.drawable.img_13,
R.drawable.img_14,
R.drawable.img_15,
R.drawable.img_16 },
{ R.drawable.img_20,
R.drawable.img_21 } };
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initData();
mListView = new ExpandableListView(this);
mListView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
setContentView(mListView);
mListView.setGroupIndicator(getResources().getDrawable(
R.drawable.expander_floder));
mAdapter = new ExpandAdapter(this, mData);
mListView.setAdapter(mAdapter);
mListView
.setDescendantFocusability(ExpandableListView.FOCUS_AFTER_DESCENDANTS);
mListView.setOnChildClickListener(this);
}
<span style="color:#ff0000;">/*
* ChildView 設置 佈局極可能onChildClick進不來,要在 ChildView layout 里加上
* android:descendantFocusability="blocksDescendants",
* 還有isChildSelectable裏返回true
*/
</span> @Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Item item = mAdapter.getChild(groupPosition, childPosition);
new AlertDialog.Builder(this)
.setTitle(item.getName())
.setMessage(item.getDetail())
.setIcon(android.R.drawable.ic_menu_more)
.setNegativeButton(android.R.string.cancel,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create().show();
return true;
}
private void initData() {
for (int i = 0; i < mGroupArrays.length; i++) {
List<Item> list = new ArrayList<Item>();
String[] childs = getStringArray(mGroupArrays[i]);
String[] details = getStringArray(mDetailIds[i]);
for (int j = 0; j < childs.length; j++) {
Item item = new Item(mImageIds[i][j], childs[j], details[j]);
list.add(item);
}
mData.add(list);
}
}
private String[] getStringArray(int resId) {
return getResources().getStringArray(resId);
}
}</span></span>
這這個demo的時候,想實現ChildView的點擊事件,實現接口onChildClick,發現不進來,很尷尬。。。最後仍是在網上找到答案了,第一,在適配器裏isChildSelectable 必須返回true,第二,ChildView佈局child_item_layout.xml最外層的layout設置個屬性:
[java]
<span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style="">android:descendantFocusability="blocksDescendants"</span></span></span></span>
上面已標示紅色的啦。
細心的同窗會發現 Item 是啥?也貼出來吧
[java] package com.xyz.expande; public class Item { private int resId; private String name; private String detail; public Item(int resId, String name, String detail) { this.resId = resId; this.name = name; this.detail = detail; } public void setImageId(int resId) { this.resId = resId; } public int getImageId() { return resId; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setDetail(String detail) { this.detail = detail; } public String getDetail() { return detail; } public String toString() { return "Item[" + resId + ", " + name + ", " + detail + "]"; } }