編輯:關於Android編程
由於工作需要,今天簡單研究了一下ExpandableListView,做了一個類似QQ列表的Demo,和大家分享一下。
效果圖如下:
先來看看主布局文件:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
這裡我們不使用系統默認的分隔線,兩個組之間的距離為8dp.
對於ExpandableListView,系統為我們提供了專門的適配器BaseExpandableListAdapter,我們可以自定義一個適配器繼承BaseExpandableListAdapter,實現該類中的一些方法即可。
代碼如下:
public class MyAdapter extends BaseExpandableListAdapter {
private List list;
private Context context;
public MyAdapter(List list, Context context) {
this.list = list;
this.context = context;
}
public MyAdapter() {
}
@Override
public int getGroupCount() {
return list.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return list.get(groupPosition).getChildren().size();
}
@Override
public Object getGroup(int groupPosition) {
return list.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return list.get(groupPosition).getChildren().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
GroupHolder holder;
if (convertView == null) {
holder = new GroupHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.item_group, null);
holder.title = (TextView) convertView
.findViewById(R.id.group_title);
holder.iv = (ImageView) convertView.findViewById(R.id.group_ico);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.title.setText(list.get(groupPosition).getGroupName());
if (isExpanded) {
holder.iv.setImageResource(R.drawable.rounds_open);
} else {
holder.iv.setImageResource(R.drawable.rounds_close);
}
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder;
if (convertView == null) {
holder = new ChildHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.item_child, null);
holder.name = (TextView) convertView.findViewById(R.id.child_name);
holder.sign = (TextView) convertView.findViewById(R.id.child_sign);
convertView.setTag(holder);
} else {
holder = (ChildHolder) convertView.getTag();
}
ChildBean cb = list.get(groupPosition).getChildren().get(childPosition);
holder.name.setText(cb.getName());
holder.sign.setText([簽名]+cb.getSign());
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class GroupHolder {
TextView title;
ImageView iv;
}
class ChildHolder {
TextView name, sign;
}
}
這裡的代碼有點長,我們稍微解釋一下,先是構造方法中傳入兩個參數,一個是數據源list,另外一個是上下文,list是一個GroupBean集合,GroupBean如下:
public class GroupBean {
private String groupName;
private List children;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public GroupBean(String groupName, List children) {
this.groupName = groupName;
this.children = children;
}
public GroupBean() {
}
}
很明顯,GroupBean有兩個屬性,一個是組名字,另外一個是該組下子項的一個集合,這個ChildBean就是每個組下面的每一個對象的數據,ChildBean代碼如下:
public class ChildBean {
private String name;
private String sign;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public ChildBean(String name, String sign) {
this.name = name;
this.sign = sign;
}
public ChildBean() {
}
}
說完list,下面就是getGroupCount()和getChildrenCount(),這個有點類似於我們使用BaseAdapter時的getCount(),不同的是這裡分別要返回每個組的數量,以及組內成員的數量,那麼組的數量當然就是list.size(),組內成員的數量由於每組不同,所以要先拿到每個組,再拿到該組裡成員的數量,代碼就是list.get(groupPosition).getChildren().size();
。接下來的兩個方法就是getGroup()和getChild()
,這個類似於BaseAdapter
中的getItem
,我們返回的時候還是組和組內的子項分開返回,代碼很簡單,就不多說了。稍微長一點的方法就是getGroupView和getChildView
,不多也都沒啥邏輯,和我們在ListView中使用BaseAdapter
中的getView
方法差不多,不同的是數據賦值的時候有差別。
我個人覺得,使用ExpandableListView
關鍵在於把數據結構搞清楚,Group和Child
搞清楚了,其他的都很簡單。
這裡我把Group的布局和Child的布局貼出來給大家看看:
item_group.xml
item_child.xml
這裡還涉及到一個圓角方框,代碼是這樣的:
item_background_select.xml
好了,所有的准備工作都已經完成,下面看看怎麼使用
public class MainActivity extends Activity {
private ExpandableListView mListView;
private MyAdapter adapter;
private List list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化數據
initData();
mListView = (ExpandableListView) this.findViewById(R.id.my_listview);
adapter = new MyAdapter(list, this);
mListView.setAdapter(adapter);
mListView.setGroupIndicator(null);
// mListView.expandGroup(0);
}
private void initData() {
list = new ArrayList();
{
List list1 = new ArrayList();
ChildBean cb1 = new ChildBean(媽媽, 123);
ChildBean cb2 = new ChildBean(爸爸, 456);
ChildBean cb3 = new ChildBean(爺爺, 789);
ChildBean cb4 = new ChildBean(妹妹, 000);
list1.add(cb1);
list1.add(cb2);
list1.add(cb3);
list1.add(cb4);
GroupBean gb1 = new GroupBean(家, list1);
list.add(gb1);
}
{
List list1 = new ArrayList();
ChildBean cb1 = new ChildBean(張三, 123);
ChildBean cb2 = new ChildBean(李四, 456);
ChildBean cb3 = new ChildBean(王五, 789);
ChildBean cb4 = new ChildBean(趙六, 000);
ChildBean cb5 = new ChildBean(風起, 1111);
ChildBean cb6 = new ChildBean(馬壩, 222);
ChildBean cb7 = new ChildBean(遷就, 3333333);
list1.add(cb1);
list1.add(cb2);
list1.add(cb3);
list1.add(cb4);
list1.add(cb5);
list1.add(cb6);
list1.add(cb7);
GroupBean gb1 = new GroupBean(我的朋友, list1);
list.add(gb1);
}
{
List list1 = new ArrayList();
ChildBean cb1 = new ChildBean(Tom, 123);
ChildBean cb2 = new ChildBean(Jerry, 456);
ChildBean cb4 = new ChildBean(Bush, 000);
list1.add(cb1);
list1.add(cb2);
list1.add(cb4);
GroupBean gb1 = new GroupBean(國際友人, list1);
list.add(gb1);
}
{
List list1 = new ArrayList();
ChildBean cb1 = new ChildBean(趙工, 123);
ChildBean cb2 = new ChildBean(馬工, 456);
ChildBean cb3 = new ChildBean(王工, 789);
ChildBean cb4 = new ChildBean(李工, 000);
ChildBean cb5 = new ChildBean(為工, 000);
list1.add(cb1);
list1.add(cb2);
list1.add(cb3);
list1.add(cb4);
list1.add(cb5);
GroupBean gb1 = new GroupBean(同事, list1);
list.add(gb1);
}
}
}
這裡有兩行代碼我稍微說一下mListView.setGroupIndicator(null);
表示不使用系統提供的展開和收起的圖標,mListView.expandGroup(0);
表示默認打開第一項。
好了,就說這些,有問題歡迎留言討論。
版權聲明:本文為博主原創文章,未經博主允許不得轉載。若有錯誤地方,還望批評指正,不勝感激。
什麼是HandlerHandler是Android消息機制的上層接口,它為我們封裝了許多底層的細節,讓我們能夠很方便的使用底層的消息機制。Handler的最常見應用場景之
Heap Viewer,Memory Monitor和Allocation Tracker是用來可視化你的app使用內存的補充工具。使用Memory Monitor To
這周的工作對Android項目多分辨率自適應進行調整。故對這方面知識進行不斷的嘗試學習。Android項目剛開始做的時候一定養成編程習慣,所有資源調用放在value中。統
一、效果:我們看到很多軟件的通訊錄在右側都有一個字母索引功能,像微信,小米通訊錄,QQ,還有美團選擇地區等等。這裡我截了一張美團選擇城市的圖片來看看; 我們今天就來實現