写这篇的原因说起来很惭愧,面试的时候被问怎么实现二级list,我没接触过expandablelistview支支吾吾的回答用listview扩展getcount(),面试官说expandablelistview很基础的东西你都没用过,接着便是一些我也回答不上了的问题。。。
回归正题,ExpandableListView是用于实现二级listview的控件,其用法几乎和listview一样,在xml中添加,代码中获取id,实现适配器,设置适配器。不同的是,使用自定义ExpandableListView时所需设置的适配器的一些方法需要重写。这里以实现3级list作为一个例子。
首先是数据的准备,这里简单准备一下数据
private Map<String, Map<String, List<String>>> dataMap = new HashMap<>();
private String[] str1 = {"first", "second", "third"};
private String[] str2 = {"1", "2", "3", "4"};
private Map<String, List<String>> childMap = new HashMap<>();
private List<String> childList = new ArrayList<>();
Map嵌套,简单的放一下数据,然后是初始化数据
private void initData(){ childList.add("f1"); childList.add("f2"); childList.add("f3"); childMap.put(str2[0], childList); childMap.put(str2[1], childList); childMap.put(str2[2], childList); childMap.put(str2[3], childList); dataMap.put(str1[0], childMap); dataMap.put(str1[1], childMap); dataMap.put(str1[2], childMap); }
private class GroupExpandableListViewAdapter extends BaseExpandableListAdapter{ @Override public Object getGroup(int parentPos){ return dataMap.get(str1[parentPos]); } @Override public Object getChild(int parentPos, int childPos){ return dataMap.get(str1[parentPos]).get(childPos); } @Override public int getGroupCount(){ return dataMap.size(); } @Override public int getChildrenCount(int parentPos){ return 1; } @Override public long getGroupId(int parentPos){ return parentPos; } @Override public long getChildId(int parentPos, int childPos){ return childPos; } @Override public boolean hasStableIds(){ return false; } @Override public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.group_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, -1); TextView groupText = (TextView) view.findViewById(R.id.group_item); groupText.setText(str1[parentPos]); return view; } @Override public View getChildView(int parentPos, int childPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_listview, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, childPos); ChildExpandableListView childExpandableListView = (ChildExpandableListView) view.findViewById(R.id.child_listview); ChildExpandableListViewAdapter childExpandableLVAdapter = new ChildExpandableListViewAdapter(); childExpandableListView.setAdapter(childExpandableLVAdapter); return view; } @Override public boolean isChildSelectable(int i, int i1){ return true; } }这里解释一下,最重要的两个:getGroupView是获取list中父级内容的,第一层的父级很简单,只有一个TextView;
public class ChildExpandableListView extends ExpandableListView { public ChildExpandableListView(Context context) { super(context); } public ChildExpandableListView(Context context, AttributeSet attrs) { super(context, attrs); } public ChildExpandableListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
private class ChildExpandableListViewAdapter extends BaseExpandableListAdapter{ @Override public Object getGroup(int parentPos){ return childMap.get(str2[parentPos]); } @Override public Object getChild(int parentPos, int childPos){ return childMap.get(str2[parentPos]).get(childPos); } @Override public int getGroupCount(){ return childMap.size(); } @Override public int getChildrenCount(int parentPos){ return childMap.get(str2[parentPos]).size(); } @Override public long getGroupId(int parentPos){ return parentPos; } @Override public long getChildId(int parentPos, int childPos){ return childPos; } @Override public boolean hasStableIds(){ return false; } @Override public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, -1); TextView childText = (TextView) view.findViewById(R.id.child_item); childText.setText(str2[parentPos]); return view; } @Override public View getChildView(int parentPos, int childPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_child_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, childPos); TextView child_child_text = (TextView) view.findViewById(R.id.child_child_item); child_child_text.setText(childMap.get(str2[parentPos]).get(childPos)); return view; } @Override public boolean isChildSelectable(int i, int i1){ return true; } }第二级中只需要加载父项和子项的内容即可。
package com.example.yxc.expandlistviewtest; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private ExpandableListView expandableListView; private Map<String, Map<String, List<String>>> dataMap = new HashMap<>(); private String[] str1 = {"first", "second", "third"}; private String[] str2 = {"1", "2", "3", "4"}; private Map<String, List<String>> childMap = new HashMap<>(); private List<String> childList = new ArrayList<>(); private GroupExpandableListViewAdapter mExpandableListAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); expandableListView = (ExpandableListView) findViewById(R.id.listview); mExpandableListAdapter = new GroupExpandableListViewAdapter(); expandableListView.setAdapter(mExpandableListAdapter); expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView expandableListView, View view, int parentPos, int childPos, long l) { Toast.makeText(MainActivity.this, "you press the childitem " + childMap.get(str2[parentPos]).get(childPos), Toast.LENGTH_SHORT).show(); return false; } }); } private void initData(){ childList.add("f1"); childList.add("f2"); childList.add("f3"); childMap.put(str2[0], childList); childMap.put(str2[1], childList); childMap.put(str2[2], childList); childMap.put(str2[3], childList); dataMap.put(str1[0], childMap); dataMap.put(str1[1], childMap); dataMap.put(str1[2], childMap); } private class GroupExpandableListViewAdapter extends BaseExpandableListAdapter{ @Override public Object getGroup(int parentPos){ return dataMap.get(str1[parentPos]); } @Override public Object getChild(int parentPos, int childPos){ return dataMap.get(str1[parentPos]).get(childPos); } @Override public int getGroupCount(){ return dataMap.size(); } @Override public int getChildrenCount(int parentPos){ return 1; } @Override public long getGroupId(int parentPos){ return parentPos; } @Override public long getChildId(int parentPos, int childPos){ return childPos; } @Override public boolean hasStableIds(){ return false; } @Override public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.group_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, -1); TextView groupText = (TextView) view.findViewById(R.id.group_item); groupText.setText(str1[parentPos]); return view; } @Override public View getChildView(int parentPos, int childPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_listview, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, childPos); ChildExpandableListView childExpandableListView = (ChildExpandableListView) view.findViewById(R.id.child_listview); ChildExpandableListViewAdapter childExpandableLVAdapter = new ChildExpandableListViewAdapter(); childExpandableListView.setAdapter(childExpandableLVAdapter); return view; } @Override public boolean isChildSelectable(int i, int i1){ return true; } } private class ChildExpandableListViewAdapter extends BaseExpandableListAdapter{ @Override public Object getGroup(int parentPos){ return childMap.get(str2[parentPos]); } @Override public Object getChild(int parentPos, int childPos){ return childMap.get(str2[parentPos]).get(childPos); } @Override public int getGroupCount(){ return childMap.size(); } @Override public int getChildrenCount(int parentPos){ return childMap.get(str2[parentPos]).size(); } @Override public long getGroupId(int parentPos){ return parentPos; } @Override public long getChildId(int parentPos, int childPos){ return childPos; } @Override public boolean hasStableIds(){ return false; } @Override public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, -1); TextView childText = (TextView) view.findViewById(R.id.child_item); childText.setText(str2[parentPos]); return view; } @Override public View getChildView(int parentPos, int childPos, boolean b, View view, ViewGroup viewGroup){ if(view == null){ LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.child_child_item, null); } view.setTag(R.layout.group_item, parentPos); view.setTag(R.layout.child_item, childPos); TextView child_child_text = (TextView) view.findViewById(R.id.child_child_item); child_child_text.setText(childMap.get(str2[parentPos]).get(childPos)); return view; } @Override public boolean isChildSelectable(int i, int i1){ return true; } } }