本文共 15216 字,大约阅读时间需要 50 分钟。
Android中多级列表可以使用ExpandableListView和SimpleExpandableListAdapter配合来实现,但是,SimpleExpandableListAdapter用起来挺麻烦的,不易理解,而且扩展性也不好,因此,自定义BaseExpandableListAdapter类的子类以及封装相关的操作,用起来会更加直观和方便,我把我设计的封装贴出来供新手参考吧。
首先上效果图,如图所示:
1. 首先设计多级列表的标题类
就像文件和文件夹可以统一地用File类来抽象一样,多级列表的一级标题和二级标题其实也可以用同一个基类来抽象,因此,我设计了一个基类和两个子类,GroupList,GroupListChild 和 GroupListParent,其实现如下所示:
(1) GroupList 多级列表标题的抽象基类
public abstract class GroupList { private final String mTitle; public GroupList(String title) { mTitle = title; } public String getTitle() { return mTitle; } public abstract ListgetChild(); public abstract int getResource(); public abstract void buildView(View v);}
(2) GroupListChild 多级列表二级标题子类
public class GroupListChild extends GroupList { public GroupListChild(String title) { super(title); } @Override public int getResource() { return R.layout.grouplist_child; } @Override public ListgetChild() { return null; } @Override public void buildView(View v) { TextView textView = (TextView)v.findViewById(R.id.GroupListChild); textView.setText(getTitle()); } }
(3) GroupListParent 多级列表一级标题子类
public class GroupListParent extends GroupList { private ListmPopListChilds; public GroupListParent(String title,List childs) { super(title); mPopListChilds = childs; } @Override public int getResource() { return R.layout.grouplist_parent; } @Override public List getChild() { return mPopListChilds; } @Override public void buildView(View v) { TextView textView = (TextView)v.findViewById(R.id.GroupListParent); textView.setText(getTitle()); }}
2. 设计BaseExpandableListAdapter的子类
我设计的子类是一种通用的Adapter子类,类的实现中并不包含具体的Layout实现,所有的Layout都由GroupList的getResource和buildView来负责,因此,可以非常灵活地修改Layout的具体实现,而不用修改Adapter的代码。
public class GroupListAdapter extends BaseExpandableListAdapter { private Context mContext; private ListmGroups; public GroupListAdapter(Context context, List groups) { this.mContext = context; this.mGroups = groups; } @Override public Object getChild(int groupPosition, int childPosition) { List chList = mGroups.get(groupPosition).getChild(); if( chList == null) { return null; } return chList.get(childPosition); } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view,ViewGroup parent) { GroupList child = (GroupList)getChild(groupPosition, childPosition); if( child == null) { return null; } if (view == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = (RelativeLayout)inflater.inflate(child.getResource(), null); } child.buildView(view); return view; } @Override public int getChildrenCount(int groupPosition) { List chList = mGroups.get(groupPosition).getChild(); if( chList == null) { return 0; } return chList.size(); } @Override public Object getGroup(int groupPosition) { return mGroups.get(groupPosition); } @Override public int getGroupCount() { return mGroups.size(); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isLastChild, View view,ViewGroup parent) { GroupList group = (GroupList)getGroup(groupPosition); if (view == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = (RelativeLayout)inflater.inflate(group.getResource(), null); } group.buildView(view); return view; } @Override public boolean hasStableIds() { return true; } @Override public boolean isChildSelectable(int arg0, int arg1) { return true; }}
3. 应用代码
为了简化,我就直接在MainActivity中使用上述封装的类来完成多级列表的功能演示,示例如下:
public class MainActivity extends Activity implements OnGroupClickListener,OnChildClickListener { private ExpandableListView mlistView; private GroupListAdapter mAdapter; private static final String[] mParentMenu = { "Book", "Video", "Audio" }; private static final String[][] mChildMenu = { { "book1", "book2", "book3", "book4" }, { "video1", "video2" }, { "audio1", "audio2", "audio3","audio4"} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mlistView = new ExpandableListView(this); mlistView.setOnGroupClickListener(this); mlistView.setOnChildClickListener(this); Listgroups = new ArrayList (); for( int i=0; i childs = new ArrayList (); for( int j=0; j
4. 相关的xml文件
(1) grouplist_child.xml 文件
(2) grouplist_parent.xml 文件
5. 总结
本文给出了Android多级列表的封装与应用的示例,个人感觉这样封装的设计可扩展性挺好的,特别是两个特点:1. 屏蔽了一级标题和二级标题的差异,统一接口;2. 将layout均放到Adapter的Item的类中去实现,让Adapter与layout脱离耦合。这两种设计思路,相信在以后的软件设计中也会经常用到。整个工程的代码在附件中,代码结构还算清楚,就不用过多解释啦,有疑问欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 获取最新的文章和资讯。
转载地址:http://nrptx.baihongyu.com/