您的位置:首页 > 其它

ExpandableListView嵌套GridView实现购物标签栏

2018-03-05 11:50 447 查看
我们在一些购物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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: