二级列表实现CheckBox单选及全选

来源:互联网 发布:淘宝网页版登录首页 编辑:程序博客网 时间:2024/05/21 09:43

首先,我们得有个实体类

public class PhonesInfo {
    public String flag;
    public String code;
    public List<DataInfo> data;

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<DataInfo> getData() {
        return data;
    }

    public void setData(List<DataInfo> data) {
        this.data = data;
    }

    public static  class DataInfo {
        public String title;
        public List<DatasInfo> datas;
        public boolean allCheck = false;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public List<DatasInfo> getDatas() {
            return datas;
        }

        public void setDatas(List<DatasInfo> datas) {
            this.datas = datas;
        }

        public boolean isAllCheck() {
            return allCheck;
        }

        public void setAllCheck(boolean allCheck) {
            this.allCheck = allCheck;
        }

        public static class DatasInfo {
            public int price;
            public String type_name;
            public List<String> msg;
            public String add_time;
            public boolean itemCheck = false;

            public int getPrice() {
                return price;
            }

            public void setPrice(int price) {
                this.price = price;
            }

            public String getType_name() {
                return type_name;
            }

            public void setType_name(String type_name) {
                this.type_name = type_name;
            }

            public List<String> getMsg() {
                return msg;
            }

            public void setMsg(List<String> msg) {
                this.msg = msg;
            }

            public String getAdd_time() {
                return add_time;
            }

            public void setAdd_time(String add_time) {
                this.add_time = add_time;
            }

            public boolean isItemCheck() {
                return itemCheck;
            }

            public void setItemCheck(boolean itemCheck) {
                this.itemCheck = itemCheck;
            }
        }
    }
}

接下来,我们的用网络请求数据,这里我们封装了个工具类

public class MyOkHttp {
    public static OkHttpClient client=new OkHttpClient();
    public static String get(String url,String key,String value){
        FormEncodingBuilder builder=new FormEncodingBuilder();
        builder.add(key,value);
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()){
                return response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

接下来就是我们的主界面了,不多说,直接上代码 


public class MainActivity extends AppCompatActivity {

    private ExpandableListView elv;
    private CheckBox cb;
    private TextView tv_count;
    private TextView tv_sum;
    private PhonesInfo phonesInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //找控件
        initView();
        //获取网络数据
        getServerData();
    }

    /**
     * 获取网络数据
     */
    private void getServerData() {
        String url = "http://api.ehuigou.com/Orders/searchCartsLog";
        MyAsyncTask task=new MyAsyncTask();
        task.execute(url);
    }

    /**
     * 找控件
     */
    private void initView() {
        elv = (ExpandableListView) findViewById(R.id.elv);
        cb = (CheckBox) findViewById(R.id.cb);
        tv_count = (TextView) findViewById(R.id.tv_count);
        tv_sum = (TextView) findViewById(R.id.tv_sum);
    }

    /**
     * 异步任务
     */
    class MyAsyncTask extends AsyncTask<String,Integer,String>{
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        //做耗时操作
        @Override
        protected String doInBackground(String... params) {
            return MyOkHttp.get(params[0],"store_id","3850");//okHttp工具类来做网络请求
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            String json=s.toString();
            Gson gson=new Gson();
            //解析数据
            phonesInfo = gson.fromJson(json, PhonesInfo.class);
            final MyAdapter adapter=new MyAdapter();
            //设置适配器
            elv.setAdapter(adapter);
            //设置一级条目默认展开
            int count=elv.getCount();
            for (int i = 0; i < count; i++) {
                elv.expandGroup(i);
            }
            //全选框的点击监听
            cb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //判断状态,若选中则
                    if (((CheckBox)v).isChecked()){
                        //遍历一级列表
                        for (int i = 0; i < phonesInfo.getData().size(); i++) {
                            //状态设为选中
                            phonesInfo.getData().get(i).setAllCheck(true);
                            //遍历二级列表
                            for (int j = 0; j < phonesInfo.getData().get(i).getDatas().size(); j++) {
                                //状态设为选中
                                phonesInfo.getData().get(i).getDatas().get(j).setItemCheck(true);
                            }
                        }
                        //刷新适配器
                        adapter.notifyDataSetChanged();
                        //求和
                        sum();
                    }else{//否则
                        //遍历一级列表
                        for (int i = 0; i < phonesInfo.getData().size(); i++) {
                            //状态设为未选中
                            phonesInfo.getData().get(i).setAllCheck(false);
                            //遍历二级列表
                            for (int j = 0; j < phonesInfo.getData().get(i).getDatas().size(); j++) {
                                //状态设为未选中
                                phonesInfo.getData().get(i).getDatas().get(j).setItemCheck(false);
                            }
                        }
                        //刷新适配器
                        adapter.notifyDataSetChanged();
                        //求和
                        sum();
                    }
                }
            });
        }
    }

    /**
     * 定义二级列表适配器
     */
    class MyAdapter extends BaseExpandableListAdapter{
        //一级列表条数
        @Override
        public int getGroupCount() {
            return phonesInfo.getData().size();
        }
        //二级列表条数
        @Override
        public int getChildrenCount(int groupPosition) {
            return phonesInfo.getData().get(groupPosition).getDatas().size();
        }
        //一级列表数据
        @Override
        public Object getGroup(int groupPosition) {
            return phonesInfo.getData().get(groupPosition);
        }
        //二级列表数据
        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return phonesInfo.getData().get(groupPosition).getDatas().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 true;
        }
        //一级列表视图
        @Override
        public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            //填充条目布局
            convertView=View.inflate(MainActivity.this,R.layout.item_parent_market,null);
            //找控件
            CheckBox cb_parent = (CheckBox) convertView.findViewById(R.id.cb_parent);
            TextView tv_number = (TextView) convertView.findViewById(R.id.tv_number);
            tv_number.setText(phonesInfo.getData().get(groupPosition).getTitle());
            //设置复选框初始状态
            if (phonesInfo.getData().get(groupPosition).isAllCheck()){
                cb_parent.setChecked(true);
            }else{
                cb_parent.setChecked(false);
            }
            //复选框设置点击监听
            cb_parent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //判断选择状态,若选中则
                    if (((CheckBox)v).isChecked()){
                        //设置全选是否选中,并且子条目选中
                        setCheck(groupPosition,true);
                    }else{
                        //设置全选是否选中,并且子条目未选中
                        setCheck(groupPosition,false);
                        //全选不选中
                        cb.setChecked(false);
                    }
                    //求和
                    sum();
                    //刷新适配器
                    notifyDataSetChanged();
                }
            });
            return convertView;
        }

        /**
         * 设置全选是否选中,并且子条目是否选中
         * @param groupPosition
         * @param flag
         */
        private void setCheck(int groupPosition,boolean flag) {
            //改变一级条目的初始状态
            phonesInfo.getData().get(groupPosition).setAllCheck(flag);
            int num=0;
            //遍历一级条目
            for (int i = 0; i < phonesInfo.getData().size(); i++) {
                //获取一级条目的状态
                boolean allCheck = phonesInfo.getData().get(i).isAllCheck();
                //若有一条未选中,则执行
                if (!allCheck){
                    num++;
                }
            }
            //若num不为0,则
            if (num==0){
                //全选设为选中
                cb.setChecked(true);
            }else{//否则
                //全选设为未选中
                cb.setChecked(false);
            }
            //遍历二级条目
            for (int i = 0; i < phonesInfo.getData().get(groupPosition).getDatas().size(); i++) {
                //设置二级条目状态与一级一致
                phonesInfo.getData().get(groupPosition).getDatas().get(i).setItemCheck(flag);
            }
        }
        //二级列表视图
        @Override
        public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            //填充视图
            convertView=View.inflate(MainActivity.this,R.layout.item_child_market,null);
            //找控件
            CheckBox cb_child = (CheckBox) convertView.findViewById(R.id.cb_child);
            TextView tv_content = (TextView) convertView.findViewById(R.id.tv_content);
            TextView tv_time = (TextView) convertView.findViewById(R.id.tv_time);
            TextView tv_pri = (TextView) convertView.findViewById(R.id.tv_pri);
            //赋值
            tv_content.setText(phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).getType_name());
            tv_time.setText(phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).getAdd_time());
            tv_pri.setText(phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).getPrice()+"");
            //设置二级条目初始状态
            if (phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).isItemCheck()){
                cb_child.setChecked(true);
            }else{
                cb_child.setChecked(false);
            }
            //复选框设置点击监听
            cb_child.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //根据复选框的选择状态来设置二级条目的状态
                    if (((CheckBox)v).isChecked()){
                        phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).setItemCheck(true);
                    }else{
                        phonesInfo.getData().get(groupPosition).getDatas().get(childPosition).setItemCheck(false);
                    }
                    int num=0;
                    //遍历一级条目
                    for (int i = 0; i < phonesInfo.getData().size(); i++) {
                        //遍历二级条目
                        for (int j = 0; j < phonesInfo.getData().get(i).getDatas().size(); j++) {
                            //获取二级条目的状态
                            boolean itemCheck = phonesInfo.getData().get(i).getDatas().get(j).isItemCheck();
                            //若有一条未选中,则执行
                            if (!itemCheck){
                                num++;
                            }
                        }
                    }
                    //若num为0,则子条目全部为选择状态
                    if (num==0){
                        //父条目设为选中状态
                        cb.setChecked(true);
                    }else{//否则
                        //父条目设为为选中
                        cb.setChecked(false);
                    }
                    //遍历二级条目
                    for (int i = 0; i < phonesInfo.getData().get(groupPosition).getDatas().size(); i++) {
                        //若有一条为未选中状态,则父条目设为未选中,并且return掉来结束循环
                        if (!phonesInfo.getData().get(groupPosition).getDatas().get(i).isItemCheck()){
                            phonesInfo.getData().get(groupPosition).setAllCheck(false);
                            notifyDataSetChanged();
                            //求和
                            sum();
                            return;
                        }
                        //若一直执行到了最后一条,则说明子条目全为选中状态,则父条目设为选中状态
                        if (i==phonesInfo.getData().get(groupPosition).getDatas().size()-1){
                            phonesInfo.getData().get(groupPosition).setAllCheck(true);
                            notifyDataSetChanged();
                            sum();
                            return;
                        }
                    }
                    //刷新
                    notifyDataSetChanged();
                    //求和
                    sum();
                }
            });
            return convertView;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    }

    /**
     * 求和方法,将选中的条目数量与总价算出来,并赋值
     */
    private void sum(){
        int num=0;
        int price=0;
        //遍历一级条目
        for (int i = 0; i < phonesInfo.getData().size(); i++) {
            //遍历二级条目
            for (int j = 0; j < phonesInfo.getData().get(i).getDatas().size(); j++) {
                //若条目为选中状态,则将数量与价格相加
                if(phonesInfo.getData().get(i).getDatas().get(j).isItemCheck()){
                    num++;
                    price+=phonesInfo.getData().get(i).getDatas().get(j).getPrice();
                }
            }
        }
        //赋值
        tv_count.setText("数量:"+num);
        tv_sum.setText("总价:"+price);
    }
}


最后是我们的布局界面

主界面的布局

<ExpandableListView
        android:id="@+id/elv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ExpandableListView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:background="#ffffff"
        android:layout_alignParentBottom="true">
        <CheckBox
            android:id="@+id/cb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:button="@drawable/checked_selector"
            android:layout_marginLeft="20dp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="全选"
            android:layout_marginLeft="20dp"/>
        <TextView
            android:id="@+id/tv_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="数量:"
            android:layout_marginLeft="20dp"/>
        <TextView
            android:id="@+id/tv_sum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="总价:"
            android:layout_marginLeft="20dp"/>
    </LinearLayout>

父条目的布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="100dp"
              android:gravity="center_vertical"
              android:orientation="horizontal"
    >

    <CheckBox
        android:id="@+id/cb_parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:focusable="false"
        android:layout_marginBottom="30dp"
        android:button="@drawable/checked_selector"
        android:layout_marginLeft="20dp"/>

    <TextView
        android:id="@+id/tv_sign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="标记"/>

    <TextView
        android:id="@+id/tv_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="12345678"/>

</LinearLayout>


子条目的布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@android:color/holo_red_light"
              android:gravity="center_vertical"
              android:orientation="horizontal"
    >

    <CheckBox

        android:id="@+id/cb_child"
        android:layout_width="wrap_content"
        android:focusable="false"
        android:button="@drawable/checked_selector"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        android:layout_marginBottom="30dp"
        android:layout_height="wrap_content"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_tel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="iphone6"/>

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="什么手机"/>

        <TextView
            android:id="@+id/tv_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="2016-12-10"/>
    </LinearLayout>

    <TextView
        android:id="@+id/tv_pri"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="¥3000.00"/>
</LinearLayout>


原创粉丝点击