重写BaseExpandableListAdapter实现Group和Child上的按钮均可点击

由于项目需要,实现一个二级列表,显示4s店,并且需要实现组和子项同时可以选择,并且将选择的项返回给activity。


1、首先建立一个shop实体类,

public class Shop implements Serializable {
    private long id;
    private String name;
    private String fullName;
    private String address;
    private String longitude;
    private String latitude;
    private int shopType;
    private long parentId;
    private boolean isChecked = false;
    private String sortLetters; // 显示数据拼音的首字母
    List<Shop> ChildShops;(子店集合,即某一个Group下的所有项)
    

    get,set方法省略...
}
2、从服务器获取数据,通过Gson转换工具,直接生成我们所需要的list<Shop>集合。

      JSONArray parentItem = new JSONArray(response);// response是从服务器获取的json格式的字符串
     for(int i=0;i<parentItem.length();i++){
        Shop shop = new Gson().fromJson(parentItem.get(i).toString(),Shop.class);
        shopList.add(shop);// 将一个个shop加入到shopList集合,用于传递到adapter.
     }
3、显示数据

     shopAdapter = new ShopAdapter(getApplicationContext(),list);// shopAdapter即重写adapter
接下来,我将重点讲这个adapter的重写

先来预览一下效果

4、定义group和child的视图

shop_parent_item.xml布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="@color/white"
    android:layout_height="wrap_content">
   
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="30dp"
            android:layout_height="match_parent">
            <ImageView
                android:id="@+id/arrowRight"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/arrow_right_18"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="1">
            <TextView
                android:id="@+id/parent_shop_name"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:text=""
                android:textColor="@color/colorHeader"
                android:textSize="14sp"/>
            <TextView
                android:id="@+id/parent_shop_address"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:text=""
                android:textSize="10sp"
                android:textColor="@color/gray"
                android:layout_marginTop="5dp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp">
            <ImageView
                android:id="@+id/parent_shop_add"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@drawable/shopadd"/>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


shop_child_item.xml定义如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="50dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="38dp"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginLeft="30dp">
            <TextView
                android:id="@+id/child_shop_type"
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textColor="@color/gray"
                android:textSize="10sp"
                android:text=""/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="1">
            <TextView
                android:id="@+id/child_shop_name"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:text=""
                android:textColor="@color/skyblue"
                android:textSize="14sp"/>
            <TextView
                android:id="@+id/child_shop_address"
                android:layout_width="match_parent"
                android:layout_height="15dp"
                android:text=""
                android:textSize="10sp"
                android:textColor="@color/gray"
                android:layout_marginTop="3dp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="20dp"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="10dp">
            <ImageView
                android:id="@+id/child_shop_add"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@drawable/shopadd"/>
        </LinearLayout>
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/gray"
        />
</LinearLayout>




5、重写BaseExpandableListAdapter,实现想要的结果。直接上代码,注释写的很清楚:

package com.iftech.zhongdugps.trace.adapter;

/**
 * Created by Tanghuosong on 2017/3/17.
 */
public class ShopAdapter extends BaseExpandableListAdapter {

    private List<Shop> shopList = new ArrayList<>();
    private LayoutInflater inflater;
    private List<Shop> shopChecked = new ArrayList<>();
    ParentViewHolder parentViewHolder;
    ChildViewHolder childViewHolder;
    // 构造函数,传入shops即activity需要显示的list
    public ShopAdapter(Context context,List<Shop> shops){
        this.shopList = shops;
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return shopList.get(groupPosition).getChildShops().size();
    }

    @Override
    public int getGroupCount() {
        return shopList.size();
    }

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        final Shop parentShop = getGroup(groupPosition);
        if(convertView==null){
            parentViewHolder = new ParentViewHolder();
            convertView = inflater.inflate( R.layout.shop_parent_item, null);
            parentViewHolder.parent_shop_name = (TextView) convertView.findViewById(R.id.parent_shop_name);
            parentViewHolder.parent_shop_address = (TextView) convertView.findViewById(R.id.parent_shop_address);
            parentViewHolder.parent_shop_add = (ImageView) convertView.findViewById(R.id.parent_shop_add);
            parentViewHolder.arrowRight = (ImageView) convertView.findViewById(R.id.arrowRight);
            convertView.setTag(parentViewHolder);
        }else{
            parentViewHolder = (ParentViewHolder)convertView.getTag();
        }
        parentViewHolder.parent_shop_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!parentShop.isChecked()){// 判断是否已经选择,选择过的再次点击则移除
                    shopChecked.add(parentShop);
                    parentShop.setChecked(true);// 点击添加按钮时将该shop加入到集合中,方便activity获得所有已经选中的。
                }else {
                    parentShop.setChecked(false);// 点击删除按钮,将该shop从集合中移除,保证选择的正确性。
                    shopChecked.remove(parentShop);
                }
                ShopAdapter.this.notifyDataSetChanged();// 通知adapter进行更新
            }
        }); 
        // 以下这段是防止右侧的点击按钮出现混乱,做的标记
        if(parentShop.isChecked()){
            parentViewHolder.parent_shop_add.setImageResource(R.drawable.shopsub);// 选择过的图片显示红叉,代表可以删除
        }else{
            parentViewHolder.parent_shop_add.setImageResource(R.drawable.shopadd);// 未选中的图标显示绿色的加号,表示可以选择
        }
       
        if(getChildrenCount(groupPosition)==0){// 当某一个组的子项数为0时,左侧箭头隐藏
            parentViewHolder.arrowRight.setVisibility(View.GONE);
        }else{
            parentViewHolder.arrowRight.setVisibility(View.VISIBLE);
        }
        parentViewHolder.parent_shop_name.setText(parentShop.getName());
        parentViewHolder.parent_shop_address.setText(parentShop.getAddress());
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition,final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final Shop childShop = getChild(groupPosition,childPosition);
        if(convertView == null){
            childViewHolder = new ChildViewHolder();
            convertView = inflater.inflate(R.layout.shop_child_item,null);
            childViewHolder.child_shop_type = (TextView) convertView.findViewById(R.id.child_shop_type);
            childViewHolder.child_shop_name = (TextView) convertView.findViewById(R.id.child_shop_name);
            childViewHolder.child_shop_address = (TextView) convertView.findViewById(R.id.child_shop_address);
            childViewHolder.child_shop_add = (ImageView) convertView.findViewById(R.id.child_shop_add);
            convertView.setTag(childViewHolder);
        }else{
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        // 以下这是该项目特殊需求,读者可以自动忽略
       if((childShop.getShopType())==2){
            childViewHolder.child_shop_type.setText("二库");
        }else{
            childViewHolder.child_shop_type.setText("二网");
        }
        // 理解同parentViewHolder
        childViewHolder.child_shop_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(!childShop.isChecked()){
                    childShop.setChecked(true);
                    shopChecked.add(childShop);
                }else{
                    childShop.setChecked(false);
                    shopChecked.remove(childShop);
                }

                ShopAdapter.this.notifyDataSetChanged();
            }
        });
        if(childShop.isChecked()){
            childViewHolder.child_shop_add.setImageResource(R.drawable.shopsub);
        }else{
            childViewHolder.child_shop_add.setImageResource(R.drawable.shopadd);
        }
        childViewHolder.child_shop_name.setText(childShop.getName());
        childViewHolder.child_shop_address.setText(childShop.getAddress());
        return convertView;
    }


    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public Shop getChild(int groupPosition, int childPosition) {
        return shopList.get(groupPosition).getChildShops().get(childPosition);
    }
    @Override
    public Shop getGroup(int groupPosition) {
        return shopList.get(groupPosition);
    }

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

    @Override
    public void onGroupExpanded(int groupPosition) {
        super.onGroupExpanded(groupPosition);
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
 
    public List<Shop> getShopChecked() {
        return shopChecked;
    }

    public void setShopChecked(List<Shop> shopChecked) {
        this.shopChecked = shopChecked;
    }

    final static class ParentViewHolder{
        private TextView parent_shop_name;
        private TextView parent_shop_address;
        private ImageView parent_shop_add;
        private TextView catalog;
        private ImageView arrowRight;
        private LinearLayout cb_layout;
    }

    final static class ChildViewHolder{
        private TextView child_shop_type;
        private TextView child_shop_name;
        private TextView child_shop_address;
        private ImageView child_shop_add;
    }

  
}
6、关于activity如何获得在adapter中选择的shop,有很多种方式,例如使用接口接听,观察者模式,而我在这里使用的最简便的方法,观察者模式(不懂观察者模式,请自行google)。

       shopAdapter.registerDataSetObserver(new DataSetObserver() {
           @Override
           public void onChanged() {
               super.onChanged();
               selectShops = shopAdapter.getShopChecked();
               for(Shop shop :selectShops){
                    Logger.d("Shop",shop.toString());
                }
                   Logger.d("已选择项数","===================>"+selectShops.size());
           }
        });
每当adapter中点击了按钮,不管是删除或者添加都可以监听到改变

7、图片中的右侧的字母搜索本篇不做介绍,想了解的也可以google查看。还有一些小的欠缺,由于时间原因没来得及做完。例如左侧箭头在该group展开时换成向下的箭头,待完善后补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值