美文网首页Android知识Android 程序员
(转)可勾选的ExpandableListView

(转)可勾选的ExpandableListView

作者: _ming_ming | 来源:发表于2016-08-05 18:13 被阅读1027次
  • 由于项目的保密性,暂时不公开源码,但是基于该博主源码,可以完美实现勾选的多级列表。
    下面是模拟最终效果图。


    最终效果图.png

加上checkbox,需要自己维护一个数据结构. 开发上要求点group list item的大多数区域是expand/collapse,仅点checkbox区域是勾选,而点child list item的任意区域都是勾选效果, 可以让列表setOnChildClickListener()。
注意ExpandableListAdapter的isChildSelectable()方法一定返回true。
编辑自http://www.allenj.net/?p=3644. 给出干货,该博主好像404了,还好保留了code精华,与他人分享。


下面是code演示。
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> 
  • Google于2013开源了:Gson,更快更轻松解析Json的利器,用过几次表示比Java自带的JsonObject要好得多。
  • Android Studio的用户可以安装插件GsonFormat。一键构造实体类。

相关文章

网友评论

    本文标题:(转)可勾选的ExpandableListView

    本文链接:https://www.haomeiwen.com/subject/vmzhsttx.html