注:本文参考http://www.eoeandroid.com/thread-81657-1-1.html加上自己在工作中的实践写出。本文的大致内容可以在那篇文章中找到,只有较小的改动,写的目的只是为了自己更好的理解。
做一个界面,需要动态加载某些混合的信息,所以没有办法在xml里直接把界面写出来。之前没弄过android开发,自己上网找办法,开始找了ListView,后来发现可以动态加载,但是没法嵌套,也就是说,第一级的item下无法动态加载第二级,费了好大的劲,找到了用ExpandableListView。
其实这个Expandable的用法跟ListView挺像的,看名字就知道了。效果图因为在手机上实现的,我也不贴出来了。
我的工作是实现一个用药提醒的功能,跟android4.2中的系统闹铃差不多,点击事件,出现了在这个时间需要服用的药品(包含药品名称,服用方法等等信息,都一样的)。实现的主要步骤有以下几个:
1.编写xml文档,需要编写三个文档,一个主文档,这个文档中声明了ExpandableListView,一个一级文档,声明一级标题中有什么组件和布局,一个二级文档,声明二级标题中有什么组件及布局。
2.在主函数中声明ExpandableListView和ExpandableAdapter类,这个ExpandableAdapter类是自己实现的一个继承了BaseExpandableListAdapter的类,重写了一些函数,这些函数主要用于查找每级标题中的内容。这个内容是如何写入的呢?答案是通过List和Map。将信息装入其中。一个ExpandableListView有一个一级标题的List,里边有很多存储一级标题的内容的Map,还有一个存储二级标题的List,但这个List中不直接包含Map,而是有很多包含了很多Map的List。
3.赋值:上边已经说了,往Map中放数据,然后把Map放在List中。
4。关键代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandableListView drugremindlist = (ExpandableListView) findViewById(R.id.drugremindlist);
ExpandableAdapter adapter = new ExpandableAdapter(this,getTimeData(),getDrugData());
drugremindlist.setAdapter(adapter);
}
private List<Map<String,Object>> getTimeData(){
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("timetext", "8:00");
list.add(map1);
Map<String,Object> map2 = new HashMap<String,Object>();
map2.put("timetext", "12:00");
list.add(map2);
Map<String,Object> map3 = new HashMap<String,Object>();
map3.put("timetext", "20:00");
list.add(map3);
return list;
}这段代码写入了一级标题的内容,吃药的时间。
private List<List<Map<String,Object>>> getDrugData(){
List<List<Map<String,Object>>> list = new ArrayList<List<Map<String,Object>>>();
List<Map<String,Object>> list1 = new ArrayList<Map<String,Object>>();
List<Map<String,Object>> list2 = new ArrayList<Map<String,Object>>();
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("drugimage", R.drawable.drug1);
map1.put("drugnametext","感抗");
map1.put("drugdetailtext", "一片 口服 空腹");
list1.add(map1);
Map<String,Object> map2 = new HashMap<String,Object>();
map2.put("drugimage", R.drawable.drug2);
map2.put("drugnametext","胶囊");
map2.put("drugdetailtext", "一片 口服 远食");
list1.add(map2);
Map<String,Object> map3 = new HashMap<String,Object>();
map3.put("drugimage", R.drawable.drug2);
map3.put("drugnametext","胶囊");
map3.put("drugdetailtext", "一片 口服 远食");
list2.add(map3);
list.add(list1);
list.add(list2);
return list;
}这段代码写入了二级标题的内容,可以看出来,是每个一级标题的内容分别写入的。
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
int drugImage = (Integer) ((Map<String,Object>)getChild(groupPosition,childPosition)).get("drugimage");
String drugNameText = (String) ((Map<String,Object>)getChild(groupPosition,childPosition)).get("drugnametext");
String drugDetailText = (String) ((Map<String,Object>)getChild(groupPosition,childPosition)).get("drugdetailtext");
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout) layoutInflater.inflate(R.layout.druglist, null);
ImageView drugImageView = (ImageView) layout.findViewById(R.id.drugimage);
TextView drugNameTextView = (TextView) layout.findViewById(R.id.drugnametext);
TextView drugDetailTextView = (TextView) layout.findViewById(R.id.drugdetailtext);
drugImageView.setImageResource(drugImage);
drugNameTextView.setText(drugNameText);
drugDetailTextView.setText(drugDetailText);
return layout;
}这个是自己实现的ExpandableAdapter类中的函数,用来返回二级标题的layout,思路是从程序中动态写入的二级标题内容中,读取内容,给你在xml中生命的组件赋值,只赋了一个二级标题的值,不用怀疑,整个类的实现其实都只针对一个标题,而非整体赋值,所以不会出现循环什么的,一般都是按照下标返回值,大概内部有机制循环调用这个类中的函数吧。
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
String timeText = (String) groups.get(groupPosition).get("timetext");
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout) layoutInflater.inflate(R.layout.timelist, null);
TextView timeTextView = (TextView) layout.findViewById(R.id.timetext);
timeTextView.setText(timeText);
return layout;
}同理,这个是获得一级标题layout的函数。