ExpandableListView nested GridView implements the shopping label bar,
In some shopping apps, we can see the following interface, classify multiple tags, select tags, and then the system filters them to select the appropriate product.
It is obvious that the nesting of ExpandableListView and GridView is simple in layout, but the interaction between the two data is difficult. Next, this article will achieve this effect. Reset: Select clear; complete: Pass the selected data to the View layer.
1. ExpandableListView is preferred. When customizing the GridView, I put all event processing at the GridView layer.
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
> MMap; private Context mContext; private CategoryExpandGridAdapter categoryExpandGridAdapter; public CategoryExpandAdapter (Context context, LinkedHashMap
> Map) {this. mContext = context; this. mMap = map;} @ Override public int getGroupCount () {Set
KeySet = mMap. keySet (); return keySet. toArray (). length ;}@ Override public int getChildrenCount (int groupPosition) {// 1 is returned here; otherwise, the returned data does not correspond to 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 ("brand"); break; case Constants. CATEGORY_PRICE_KEY: viewHolder. textView. setText ("price"); break; case Constants. CATEGORY_LOCATION_KEY: viewHolder. textView. setText ("region"); break; case Constants. CATEGORY_SCALE_KEY: viewHolder. textView. setText ("discount"); break; case Constants. CATEGORY_SIZE_KEY: viewHolder. textView. setText ("size"); 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
List = mMap. get (key); categoryExpandGridAdapter = new CategoryExpandGridAdapter (list, mContext, groupPosition); childViewHolder. gridView. setAdapter (categoryExpandGridAdapter); return view;} // obtain the selected Map
GetCheckedString () {if (null! = CategoryExpandGridAdapter) {return categoryExpandGridAdapter. getCheckedString ();} return null;} // clear 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. Implementation of the GridView
A. ExpandableListView nested GridView will cause a sliding conflict. Therefore, you need to perform special processing on the GridView. The processing method is the same as that on the Internet:
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. the implementation of the GridView adapter, here I use RadioButton, of course, can also use Checkbox, in the implementation process, the most difficult is that I did not expect to use a static set to load data, resulting in a variety of methods, there is only one data entry in the set.
Public class CategoryExpandGridAdapter extends BaseAdapter {private List
MData; private Context mContext; private int mGroupPosition; private Set
CheckBoxList = new HashSet <> (); @ SuppressLint ("UseSparseArrays") private HashMap
> Map = new HashMap <> (); // use static data to ensure that all data is placed in the set. set prevents repeated private static Map objects.
> RadioButtonHashMap = new LinkedHashMap <> (); // transmits groupPostion and determines the key public CategoryExpandGridAdapter (List
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
CheckList = (Set
) 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
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
GetCheckedString () {Map
Strings = new LinkedHashMap <> (); Set
Integers = radioButtonHashMap. keySet (); for (int id: integers) {Set
RadioButtons = radioButtonHashMap. get (id); for (RadioButton radioButton: radioButtons) {if (radioButton. isChecked () {strings. put (id, radioButton. getText (). toString () ;}}return strings;} void clearChecked () {Set
Integers = radioButtonHashMap. keySet (); for (int id: integers) {Set
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. Check the effect: