在讲解之前先说两句,本文仅仅介绍了adapter的使用方法。并没有深入研究其中的区别。
下面以ListView为例讲解adapter的应用和区别
列表的显示需要三个元素:
1.ListVeiw 用来展示列表的View。
2.适配器 用来把数据映射到ListView上的中介。
3.数据 具体的将被映射的字符串,图片,或者基本组件。
根据列表的适配器类型,列表分为三种,ArrayAdapter,SimpleAdapter和SimpleCursorAdapter
在layout.xml中创建ListView
<ListView
android:id="@+id/listview1"
android:entries="@array/ctype"//获取资源文件数组
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:divider="@color/mycolor1"
android:dividerHeight="3sp"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false" >
二,ListAdapter
1,ListAdapter是绑定Data和Listview的适配器。但是,它是接口,需要使用它的子类。
常见的子类有:arrayAdapter,SimpleAdapter ,CursorAdapter 等
Android.R.layout.simple_list_item_1:每一项只有一个TextView
Android.R.layout.simple_list_item_2:每一项有两个TextView
Android.R.layout.simpte.list_item_single_choice,每一项有一个TextView,但是这一项可以被选中。
三,ArrayAdapter (Basedapter的子类)
应用范围:方便实现只显示一行文本的列表
(直接去new ArrayAdapter() 来绘制列表,无须继承ArrayAdapter,重写它的方法。但是如果列表中过于复杂的话就需要使用自定义布局来实现List列表。)
public ArrayAdapter (Context context, int textViewResourceId, T[] objects)
ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()完成适配的最后工作。布局文件可以自己写,我这里是用的系统的。自己写的布局中包含一个TextView就可以了Android.R.layout.simple_expandable_list_item_1是android里已提供的样式,我们也可换成自己的xml。但是需要注意的是这个xml文件仅能有一个textview。连Layout也不能有。否则会报错:ArrayAdapter requires the resource ID to be a TextView
ListView的每个TextView里边显示的内容就是数组里边的对象调用toString()方法后生成的字符串。
ListView listview=new ListView(this);
String[] data = {“google”,”amazon”,”facebook”};
listview.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_single_choice, data));
list.setItemsCanFocus(true);
list.setChoiceMode(listview.CHOICE_MODE_MULTIPLE);
setContentView(listview);
添加监听方法:
listView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,
//parent指父View本身,第二个参数指ListView里面的每个小项即TestView
int position, long id) {//position指当前点的行号
String result = parent.getItemAtPosition(position).toString();
Toast.makeText(ListViewActivity.this, result, Toast.LENGTH_LONG).show();
}
} );
四,SimpleAdapter
应用范围:实现带图片,复杂点的ListView列表
使用 simpleAdapter 来操作 但是构造simpleAdapter的时候须要使用我们自己写的布局来完成 ,因为系统的布局已经不能满足需求了,同样Map<String,Object> item 来保存列表中每一项须要的显示内容 如 图片 标题 内容等
2,SimpleAdapter的构造函数:
SimpleAdapter(Context context, List> data, int resource, String[] from, int[] to)
参数:
1,context:上下文。
2,data:基于Map的list。Data里边的每一项都和ListView里边的每一项对应。Data里边的每一项都是一个Map类型,这个Map类里边包含了ListView每一行需要的数据。
3,resource :就是一个布局layout,可引用系统提供的,也可以自定义。
4,from:这是个名字数组,每个名字是为了在ArrayList数组的每一个item索引Map的Object用的。
5,to:里面是一个TextView数组。这些TextView是以id的形式来表示的。例如:Android.R.id.text1,这个text1在layout当中是可以索引的。
3,通过一个类子来理解下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight">
<ImageView android:id="@+id/image"
android:layout_width="wrap_content" android:layout_height="fill_parent"
android:layout_alignParentTop="true" android:layout_alignParentBottom="true"
android:adjustViewBounds="true"
android:padding="2dip" />
<TextView android:id="@+id/title"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@+id/image"
android:layout_alignParentRight="true" android:layout_alignParentTop="true"
android:layout_above="@+id/text"
android:layout_alignWithParentIfMissing="true" android:gravity="center_vertical"
android:textSize="15dip" />
<TextView android:id="@+id/text"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_toRightOf="@+id/image"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" android:singleLine="true"
android:ellipsize="marquee"
android:textSize="20dip" />
</RelativeLayout>
public class IconList extends ListActivity {
private String[] mListTitle = { "姓名", "性别", "年龄", "居住地","邮箱"};
private String[] mListStr = { "雨松MOMO", "男", "25", "北京",
"xuanyusong@gmail.com" };
ListView mListView = null;
ArrayList<Map<String,Object>> mData= new ArrayList<Map<String,Object>>();;
@Override
protected void onCreate(Bundle savedInstanceState) {
mListView = getListView();
int lengh = mListTitle.length;
for(int i =0; i < lengh; i++) {
Map<String,Object> item = new HashMap<String,Object>();
item.put("image", R.drawable.jay);
item.put("title", mListTitle[i]);
item.put("text", mListStr[i]);
mData.add(item);
}
SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.iconlist,
new String[]{"image","title","text"},new int[]{R.id.image,R.id.title,R.id.text});
setListAdapter(adapter);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
long id) {
Toast.makeText(IconList.this,"您选择了标题:" + mListTitle[position] + "内容:"+mListStr[position], Toast.LENGTH_LONG).show();
}
});
super.onCreate(savedInstanceState);
}
}
五.BaseAdapter
应用范围:实现复杂布局
simpleadapter 相对于这个 Baseadapter 来说呢,就有点太 过于简单了!这里的简单呢!不是说是他的用法以及否认他的级别,而是说呢在应用方面在某些方面
实现复杂布局可能会出现莫名错误。(具体我也没遇见过,听说simpleadapter 在转换图片的格式的时候,可能会将图片损坏)
BaseAdapter可以实现复杂的列表布局,由于BaseAdapter是一个抽象类,使用该类需要自己写一个适配器继承该类,
正是由于继承了该类,需要我们重写一些方法,让我们可以在代码里控制列表的样式,更加灵活。
public class MyBaseAdapter extends BaseAdapter{
private LayoutInflater mInflater;
public MyAdapter(Context context){
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder=new ViewHolder();
convertView = mInflater.inflate(R.layout.vlist2, null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.title = (TextView)convertView.findViewById(R.id.title);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
holder.title.setText((String)mData.get(position).get("title"));
holder.info.setText((String)mData.get(position).get("info"));
//给每一个列表后面的按钮添加响应事件
holder.viewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showInfo();
}
});
return convertView;
}
public final class ViewHolder{
public ImageView img;
public TextView title;
public TextView info;
public Button viewBtn;
}
总结: 继承其中任何一个adapter(arrayAdapter,SimpleAdapter,BaseAdapter)并重新其中的getView()方法都可以实现复杂布局。但是对于复杂布局建议继承BaseAdapter。关于原因,上面也简单提到了一些。
参考:
http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html
http://www.cnblogs.com/shang53880/archive/2011/03/15/1985062.html
http://www.xuanyusong.com/archives/91