转载请保留原文出处“http://my.oschina.net/gluoyer/blog”,谢谢!php
您能够到博客的“友情连接”中,“程序猿媛(最新下载)*.*”下载最新版本,持续更新!当前版本,也可直接点击“当前1.2版本”下载。java
本文介绍,利用ExpandableListView列表展现,并可选择各个列表项。数组
首先,看下实现效果:app
下面,介绍实现关键步骤,ide
代码里主要自定义了ExpListAdapter,继承自BaseExpandableListAdapter。里面会须要重写一些方法。须要重写的方法不少,其关键:布局
是构造方法中数据的建立;ui
组项在getGroupView中的更新;this
二级列表在getChildView中的更新。.net
另外,能够关注的方法有:3d
点击组项,列表展开事件的处理;
以及,子列表项点击事件的设置。
下面,依次介绍:
由于只是思路的阐述,这里使用了固定数据作演示:
// 在array.xml中定义了子列表的数组 private int[] childResIds = new int[] { R.array.array_explist_child_wei_name, R.array.array_explist_child_shu_name, R.array.array_explist_child_wu_name }; // 存储组数据 private ArrayList<SelectChildData> list; // 记录选择的子项 private HashMap<Integer, HashSet<Integer>> mSelectIds; @SuppressLint("UseSparseArrays") public ExpListAdapter() { mSelectIds = new HashMap<Integer, HashSet<Integer>>(); list = new ArrayList<SelectChildData>(); String[] parent = getResources().getStringArray(R.array.array_explist_title_name); getResources().getStringArray(R.array.array_explist_child_wei_name); for(int i=0, size=parent.length; i<size; i++) { SelectChildData p = new SelectChildData(); String[] child = getResources().getStringArray(childResIds[i]); ArrayList<SelectChildData> cl = new ArrayList<SelectChildData>(); for(int j=0, len=child.length; j<len; j++) { SelectChildData c = new SelectChildData(); c.id = j; c.name = child[j]; cl.add(c); } p.id = i; p.name = parent[i]; p.children = cl; list.add(p); mSelectIds.put(i, new HashSet<Integer>()); } }
若是须要是动态数据的话,在构造方法中,只进行成员变量的建立,不赋值。在须要的时候,经过方法调用进行动态添加便可,请根据实际使用状况扩展,不赘述!
其中,主要是布局的加载,和数据的设置,代码以下:
@Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { // 加载组布局,获取内容 GroupViewHolder holder; if(null == convertView) { convertView = View.inflate(ExpListSelectActivity.this, R.layout.explist_group_item, null); holder = new GroupViewHolder(); holder.mTitle = (TextView) convertView.findViewById(R.id.explist_group_title); holder.mSelNum = (TextView) convertView.findViewById(R.id.explist_group_selected_num); holder.mIndicator = (ImageView) convertView.findViewById(R.id.explist_group_indicator); convertView.setTag(holder); } else { holder = (GroupViewHolder) convertView.getTag(); } // 获取数据 SelectChildData data = (SelectChildData) getGroup(groupPosition); // 标题设置 holder.mTitle.setText(data.name); // 当前选择内容数量,和总数,显示如:(1/10) ArrayList<SelectChildData>list = data.children; int cnt = 0, num = 0; if(null != list && !list.isEmpty()) { HashSet<Integer> cids = mSelectIds.get(groupPosition); for(SelectChildData d : list) { if(cids.contains(d.id)) { num ++; } } cnt = list.size(); } holder.mSelNum.setText( String.format(getResources().getString(R.string.str_trans_receiver_num), num, cnt)); // 设置右侧显示图标 if(isExpanded) { holder.mIndicator.setImageResource(R.drawable.icon_sub); convertView.setSelected(true); } else { holder.mIndicator.setImageResource(R.drawable.icon_add); convertView.setSelected(false); } return convertView; }
同组数据相似,主要也是布局的加载,和数据的设置,限于版面,就不贴代码了,请须要的猿媛下载查看源码。
在这里,我是在点击某项展开的时候,将展开的项进行了收缩,处理以下:
@Override public void onGroupExpanded(int groupPosition) { // mExpListView 是列表实例,经过判断它的状态,关闭已经展开的。 for(int i=0, cnt=getGroupCount(); i<cnt; i++) { if(groupPosition != i && mExpListView.isGroupExpanded(i)) { mExpListView.collapseGroup(i); } } super.onGroupExpanded(groupPosition); }
代码中,定义了子列表项点击监听,在里面更新选择子项的内容记录。
// 定义监听事件,子列表项点击后,调用Adapter的方法进行更新 private OnChildClickListener mOnChildClickListener = new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { mExpListAdapter.onChildClick(groupPosition, childPosition); return true; } }; // Adapter中的子列表项点击处理方法 // 根据列表自身特性,经过从0开始的位置,做为key进行记录 public void onChildClick(int groupPosition, int childPosition) { HashSet<Integer> children = mSelectIds.get(groupPosition); if(children.contains(childPosition)) { children.remove(childPosition); } else { children.add(childPosition); } notifyDataSetChanged(); }
最后,能够在文初的截图中看到,点击“肯定”按钮,经过Toast显示了选择的内容,获取内容的方法在ExpListAdapter中定义,主要是对记录的内容进行了拼接,以下:
public String getSelectInfo() { StringBuilder s = new StringBuilder(); for(int i=0, size=mSelectIds.size(); i<size; i++) { HashSet<Integer> children = mSelectIds.get(i); // 记录不为空,则遍历列表去查找。 if(!children.isEmpty()) { s.append(list.get(i).name); s.append(": "); ArrayList<SelectChildData> cl = list.get(i).children; for(int j=0, len=cl.size(); j<len; j++) { if(children.contains(cl.get(j).id)) { s.append(cl.get(j).name); s.append(" "); } } s.append("\n"); } } if(s.length() > 0) { return s.toString(); } else { return "No Selection"; } }
Ok,基本点就这些了,应用安装后的源码获取,及获取后文件结构的状况,能够参考“程序猿媛”系列博文的第一篇:Android滑动翻页+区域点击事件
转载请保留原文地址“http://my.oschina.net/gluoyer/blog/176925”,谢谢!
您能够到博客的“友情连接”中,“程序猿媛(最新下载)*.*”下载最新版本,持续更新!当前版本,也可直接点击“当前1.2版本”下载。