加上checkbox,需求大抵都是:check group, check all his children; if one' group's children all checked, group become checked. ExpandableListView的选中状态没有类似SparseBooleanArray的东东,需要自己维护一个数据结构. 开发上要求点group list item的大多数区域是expand/collapse,仅点checkbox区域是勾选,而点child list item的任意区域都是勾选效果, 可以让列表setOnChildClickListener()。注意ExpandableListAdapter的isChildSelectable()方法一定返回true。

编辑自http://www.allenj.net/?p=3644. 给出干货:

EListAdapter.java

package com.example.checkableexpandablelistview;import java.util.ArrayList;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseExpandableListAdapter;import android.widget.CheckBox;import android.widget.ExpandableListView;import android.widget.TextView;import com.example.aexpandablelist.R;public class EListAdapter extends BaseExpandableListAdapter implements ExpandableListView.OnChildClickListener {  private Context context; private ArrayList<Group> groups; public EListAdapter(Context context, ArrayList<Group> groups) { this.context = context; this.groups = groups; } public Object getChild(int groupPosition, int childPosition) { return groups.get(groupPosition).getChildItem(childPosition); } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public int getChildrenCount(int groupPosition) { return groups.get(groupPosition).getChildrenCount(); } public Object getGroup(int groupPosition) { return groups.get(groupPosition); } public int getGroupCount() { return groups.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public boolean hasStableIds() { return true; } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } /** 設定 Group 資料 */ public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { Group group = (Group) getGroup(groupPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.group_layout, null); } TextView tv = (TextView) convertView.findViewById(R.id.tvGroup); tv.setText(group.getTitle()); // 重新產生 CheckBox 時,將存起來的 isChecked 狀態重新設定 CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.chbGroup); checkBox.setChecked(group.getChecked()); // 點擊 CheckBox 時,將狀態存起來 checkBox.setOnClickListener(new Group_CheckBox_Click(groupPosition)); return convertView; } /** 勾選 Group CheckBox 時,存 Group CheckBox 的狀態,以及改變 Child CheckBox 的狀態 */ class Group_CheckBox_Click implements OnClickListener { private int groupPosition; Group_CheckBox_Click(int groupPosition) { this.groupPosition = groupPosition; } public void onClick(View v) { groups.get(groupPosition).toggle(); // 將 Children 的 isChecked 全面設成跟 Group 一樣 int childrenCount = groups.get(groupPosition).getChildrenCount(); boolean groupIsChecked = groups.get(groupPosition).getChecked(); for (int i = 0; i < childrenCount; i++) groups.get(groupPosition).getChildItem(i).setChecked(groupIsChecked); // 注意,一定要通知 ExpandableListView 資料已經改變,ExpandableListView 會重新產生畫面 notifyDataSetChanged(); } } /** 設定 Children 資料 */ public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { Child child = groups.get(groupPosition).getChildItem(childPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.child_layout, null); } TextView tv = (TextView) convertView.findViewById(R.id.tvChild); tv.setText(child.getFullname()); // 重新產生 CheckBox 時,將存起來的 isChecked 狀態重新設定 CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.chbChild); checkBox.setChecked(child.getChecked()); // 點擊 CheckBox 時,將狀態存起來 checkBox.setOnClickListener(new Child_CheckBox_Click(groupPosition, childPosition)); return convertView; } /** 勾選 Child CheckBox 時,存 Child CheckBox 的狀態 */ class Child_CheckBox_Click implements OnClickListener { private int groupPosition; private int childPosition; Child_CheckBox_Click(int groupPosition, int childPosition) { this.groupPosition = groupPosition; this.childPosition = childPosition; } public void onClick(View v) { handleClick(childPosition, groupPosition); } }  public void handleClick(int childPosition, int groupPosition) { groups.get(groupPosition).getChildItem(childPosition).toggle();  // 檢查 Child CheckBox 是否有全部勾選,以控制 Group CheckBox int childrenCount = groups.get(groupPosition).getChildrenCount(); boolean childrenAllIsChecked = true; for (int i = 0; i < childrenCount; i++) { if (!groups.get(groupPosition).getChildItem(i).getChecked()) childrenAllIsChecked = false; } groups.get(groupPosition).setChecked(childrenAllIsChecked); // 注意,一定要通知 ExpandableListView 資料已經改變,ExpandableListView 會重新產生畫面 notifyDataSetChanged(); } @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { handleClick(childPosition, groupPosition); return true; } }

Group.java

package com.example.checkableexpandablelistview;import java.util.ArrayList;public class Group {    private String id;    private String title;    private ArrayList<Child> children;    private boolean isChecked;     public Group(String id, String title) {        this.title = title;        children = new ArrayList<Child>();        this.isChecked = false;    }     public void setChecked(boolean isChecked) {        this.isChecked = isChecked;    }     public void toggle() {        this.isChecked = !this.isChecked;    }     public boolean getChecked() {        return this.isChecked;    }     public String getId() {        return id;    }     public String getTitle() {        return title;    }     public void addChildrenItem(Child child) {        children.add(child);    }     public int getChildrenCount() {        return children.size();    }     public Child getChildItem(int index) {        return children.get(index);    }}



Child.java

package com.example.checkableexpandablelistview;public class Child {    private String userid;    private String fullname;    private String username;    private boolean isChecked;     public Child(String userid, String fullname, String username) {        this.userid = userid;        this.fullname = fullname;        this.username = username;        this.isChecked = false;    }     public void setChecked(boolean isChecked) {        this.isChecked = isChecked;    }     public void toggle() {        this.isChecked = !this.isChecked;    }     public boolean getChecked() {        return this.isChecked;    }     public String getUserid() {        return userid;    }     public String getFullname() {        return fullname;    }     public String getUsername() {        return username;    }}


MainActivity.java

package com.example.checkableexpandablelistview;import java.util.ArrayList;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.widget.ExpandableListView;import com.example.aexpandablelist.R;public class MainActivity extends Activity { ArrayList<Group> groups; ExpandableListView listView; EListAdapter adapter;  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); groups = new ArrayList<Group>(); getJSONObject(); listView = (ExpandableListView) findViewById(R.id.listView); adapter = new EListAdapter(this, groups); listView.setAdapter(adapter); listView.setOnChildClickListener(adapter); } /** 解悉 JSON 字串 */ private void getJSONObject() { String jsonStr = "{'CommunityUsersResult':[{'CommunityUsersList':[{'fullname':'a111','userid':11,'username':'a1'}" + ",{'fullname':'b222','userid':12,'username':'b2'}],'id':1,'title':'人事部'},{'CommunityUsersList':[{'fullname':" + "'c333','userid':13,'username':'c3'},{'fullname':'d444','userid':14,'username':'d4'},{'fullname':'e555','userid':" + "15,'username':'e5'}],'id':2,'title':'開發部'}]}"; try { JSONObject CommunityUsersResultObj = new JSONObject(jsonStr); JSONArray groupList = CommunityUsersResultObj.getJSONArray("CommunityUsersResult"); for (int i = 0; i < groupList.length(); i++) { JSONObject groupObj = (JSONObject) groupList.get(i); Group group = new Group(groupObj.getString("id"), groupObj.getString("title")); JSONArray childrenList = groupObj.getJSONArray("CommunityUsersList"); for (int j = 0; j < childrenList.length(); j++) { JSONObject childObj = (JSONObject) childrenList.get(j); Child child = new Child(childObj.getString("userid"), childObj.getString("fullname"), childObj.getString("username")); group.addChildrenItem(child); } groups.add(group); } } catch (JSONException e) { Log.d("allenj", e.toString()); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }}


activity_main.xml

<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" >    <ExpandableListView        android:id="@+id/listView"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    </ExpandableListView></RelativeLayout>

group_layout.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" >    <TextView        android:id="@+id/tvGroup"        android:layout_width="280dp"        android:layout_height="45dip"        android:gravity="center_vertical|left"        android:paddingLeft="45dp"        android:textSize="17dip"        android:textStyle="bold" >    </TextView>    <CheckBox        android:id="@+id/chbGroup"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:focusable="false" /></LinearLayout>

child_layout.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" > <TextView android:id="@+id/tvChild" android:layout_width="280dp" android:layout_height="45dip" android:gravity="center_vertical" android:paddingLeft="45dp" android:textSize="17dip" android:textStyle="bold" > </TextView> <CheckBox android:id="@+id/chbChild" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusable="false" /></LinearLayout>


更多相关文章

  1. Android创建并更新通知栏通知
  2. Android(安卓)底部导航栏BottomNavigationView的使用
  3. Android:SystemUi有关notification
  4. Android(安卓)Notification.Builder通知案例分享
  5. WebView设置之WebViewClient
  6. android camera拍摄surfaceview预览界面特定区域(该区域可移动)
  7. 【Android】通知的实现
  8. Android(安卓)通知栏自定义样式
  9. Android(安卓)Notification基础使用(兼容 Android(安卓)8.0)

随机推荐

  1. Android(安卓)4.4以上使用HttpURLConnect
  2. Suggestion: add 'tools:replace="androi
  3. Android把Bitmap保存为PNG图像文件的简单
  4. Gradle 修改生成apk时的文件名
  5. Android启动界面实现
  6. Android 读取Resources和Assets
  7. android 重力传感器的使用
  8. android获取手机序列号
  9. Android(安卓)HandlerThread 消息循环机
  10. 汇总各种Android 蓝牙各种UUID