ExpandableListView嵌套GridView实现购物标签栏

我们在一些购物App上都会看到下面这样的界面,分类下多个标签,选择标签后,系统进行筛选,为用户选择合适的产品


看到这样的界面很明显就是ExpandableListView和GridView的嵌套,布局实现简单,但是两者之间数据的交互确是难点,接下来本文就来实现这样的效果,重置:选择清空;完成:将选择的数据传递到View层。

1.首选实现ExpandableListView,在自定义GridView时我将事件的处理都放在了GridView层

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import com.anshi.expanablegridchoice.utils.Constants;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 * Created by yulu on 2018/2/24.
 */

public class CategoryExpandAdapter extends BaseExpandableListAdapter {
    private LinkedHashMap<String,List<String>> mMap;
    private Context mContext;
    private CategoryExpandGridAdapter categoryExpandGridAdapter;

    public CategoryExpandAdapter(Context context,LinkedHashMap<String,List<String>> map){
        this.mContext = context;
        this.mMap = map;
    }

    @Override
    public int getGroupCount() {
        Set<String> keySet = mMap.keySet();
        return keySet.toArray().length;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        //此处需要返回1,否则会出现数据不对应
        return 1;
    }

    @Override
    public Object getGroup(int groupPosition) {

        return null;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return null;
    }

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

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

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        View view = convertView;
        CategoryExpandViewHolder viewHolder;
        if (null==view){
            view = LayoutInflater.from(mContext).inflate(R.layout.category_expand_item,parent,false);
            viewHolder = new CategoryExpandViewHolder(view);
        }else {
            viewHolder = (CategoryExpandViewHolder) view.getTag();
        }
        Object[] objects = mMap.keySet().toArray();
        String key = (String) objects[groupPosition];
        switch (key){
            case Constants.CATEGORY_BRAND_KEY:
                viewHolder.textView.setText("品牌");
                break;
            case Constants.CATEGORY_PRICE_KEY:
                viewHolder.textView.setText("价格");
                break;
            case Constants.CATEGORY_LOCATION_KEY:
                viewHolder.textView.setText("地区");
                break;
            case Constants.CATEGORY_SCALE_KEY:
                viewHolder.textView.setText("优惠");
                break;
            case Constants.CATEGORY_SIZE_KEY:
                viewHolder.textView.setText("尺码");
                break;
        }
        return view;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        View view = convertView;
        CategoryExpandChildViewHolder childViewHolder;
        if (null==view){
            view = LayoutInflater.from(mContext).inflate(R.layout.category_child_item,parent,false);
            childViewHolder = new CategoryExpandChildViewHolder(view);
        }else {
            childViewHolder = (CategoryExpandChildViewHolder) view.getTag();
        }
        Object[] objects = mMap.keySet().toArray();
        String key = (String) objects[groupPosition];
        List<String> list = mMap.get(key);
        categoryExpandGridAdapter = new CategoryExpandGridAdapter(list,mContext,groupPosition);
        childViewHolder.gridView.setAdapter(categoryExpandGridAdapter);
        return view;
    }
    //获取选择数据
    Map<Integer, String> getCheckedString(){
        if (null!=categoryExpandGridAdapter){
            return categoryExpandGridAdapter.getCheckedString();
        }
        return null;
    }
    //清空选择
     void clear(){
        if (null!=categoryExpandGridAdapter){
           categoryExpandGridAdapter.clearChecked();
        }
    }

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


    private class CategoryExpandViewHolder{
        TextView textView;
        CategoryExpandViewHolder(View view){
            textView = view.findViewById(R.id.category_expand_title);
            view.setTag(this);
        }
    }
    private class CategoryExpandChildViewHolder{
        CanScrollGridView gridView;
        CategoryExpandChildViewHolder(View view){
            gridView = view.findViewById(R.id.category_expand_grid_item);
            view.setTag(this);
        }
    }
}

2.GridView的实现

a.ExpandableListView嵌套GridView会引起滑动冲突,因此,需要对GridView做特殊处理,处理方式和网上一致:

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;

/**
 *
 * Created by yulu on 2018/1/12.
 */

public class CanScrollGridView extends GridView{
    public CanScrollGridView(Context context) {
        super(context);
    }

    public CanScrollGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightSpec);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        requestDisallowInterceptTouchEvent(true);
        return super.onInterceptTouchEvent(ev);
    }
}

b.GridView适配器的实现,此处我使用了RadioButton,当然也可以使用Checkbox,我在实现过程中,最难的就是没想到要使用静态集合装载数据,导致尝试多种方法,集合中的数据只有1条

public class CategoryExpandGridAdapter extends BaseAdapter{
    private List<String>  mData;
    private Context mContext;
    private int mGroupPosition;
    private Set<RadioButton> checkBoxList  = new HashSet<>();
    @SuppressLint("UseSparseArrays")
    private HashMap<Integer,Set<RadioButton>> map= new HashMap<>();
    //使用静态确保数据全部被放置到集合中,set防止对象重复
    private static Map<Integer,Set<RadioButton>> radioButtonHashMap = new LinkedHashMap<>();
    //传递groupPostion,确定选择标签对应的key
    public CategoryExpandGridAdapter(List<String> list, Context context, int groupPosition){
        this.mData = list;
        this.mContext = context;
        this.mGroupPosition = groupPosition;
    }

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
                    Bundle data = msg.getData();
                    Set<RadioButton> checkList = (Set<RadioButton>) data.getSerializable("checkList");
                    radioButtonHashMap.put(msg.arg1,checkList);
        }
    };
    @Override
    public int getCount() {
        return null==mData?0:mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = convertView;
        final GridViewHolder gridViewHolder;
        if (null==view){
            view = LayoutInflater.from(mContext).inflate(R.layout.category_expand_grid_item,parent,false);
            gridViewHolder = new GridViewHolder(view);
        }else {
            gridViewHolder = (GridViewHolder) view.getTag();
        }
        gridViewHolder.tag.setText(mData.get(position));
        gridViewHolder.tag.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final Set<RadioButton> checkBoxes = map.get(mGroupPosition);
                if (checkBoxes!=null&&checkBoxes.size()>0){
                    for (RadioButton c:checkBoxes) {
                        if (c.isChecked()){
                            c.setChecked(false);
                        }
                    }
                }
                if (((RadioButton)v).isChecked()){
                    checkBoxList.add((RadioButton) v);
                    Message message = mHandler.obtainMessage();
                    Bundle bundle = new Bundle();
                    bundle.putSerializable("checkList", (Serializable)checkBoxList);
                    message.setData(bundle);
                    message.arg1 = mGroupPosition;
                    mHandler.sendMessage(message);
                }
                gridViewHolder.tag.setChecked(true);
                map.put(mGroupPosition,checkBoxList);

            }
        });
        return view;
    }

    Map<Integer,String> getCheckedString(){
        Map<Integer,String> strings = new LinkedHashMap<>();
        Set<Integer> integers = radioButtonHashMap.keySet();
        for (int id:integers) {
            Set<RadioButton> radioButtons = radioButtonHashMap.get(id);
            for (RadioButton radioButton:radioButtons) {
                if (radioButton.isChecked()){
                    strings.put(id,radioButton.getText().toString());
                }
            }
        }
        return strings;
    }

    void clearChecked(){
        Set<Integer> integers = radioButtonHashMap.keySet();
        for (int id:integers) {
            Set<RadioButton> radioButtons = radioButtonHashMap.get(id);
            for (RadioButton radioButton:radioButtons) {
                if (radioButton.isChecked()){
                    radioButton.setChecked(false);
                }
            }
        }
    }

    private class GridViewHolder{
        RadioButton tag;
        GridViewHolder(View view){
            tag = view.findViewById(R.id.catrgory_tag_rb);
            view.setTag(this);
        }
    }
}

3.看下效果:


源码:https://github.com/yulu1121/ExpanableGridChoice

猜你喜欢

转载自blog.csdn.net/hardWork_yulu/article/details/79442612