ArrayAdapter
总是感觉写自己的博客才更能够学到东西,网上尽管有很多好的资料,但是参差不齐,需要浪费大量时间才能够找到最需要的,索性写自己最需要的东西。
Adapter是适配器的意思,在Android中大量的使用到了ListView,而ListView需要与各种适配器结合才能够使用。不同的场合使用不同的适配器,所以总结一下最常用的会对自己以后很有帮助
ArrayAdapter(数组适配器)一般用于显示一行文本信息,所以比较容易。
public ArrayAdapter(Context context,int textViewResourceId,List<T> objects)
上面的这行代码来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,可以参见main.xml文件,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()将ListView和Adapter绑定。
例子一:可以用来简单的显示一条文字
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="cnblogs--花郎" /> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Activity
package com.loulijun.demo14; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class Demo13Activity extends Activity { private ListView lv; private ArrayList<String> list = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView)findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, android.R.layout.simple_expandable_list_item_1, getData()); lv.setAdapter(adapter); } private ArrayList<String> getData() { list.add("180平米的房子"); list.add("一个勤劳漂亮的老婆"); list.add("一辆宝马"); list.add("一个强壮且永不生病的身体"); list.add("一个喜欢的事业"); return list; } }
注意:这里的android.R.layout.simple_expandable_list_item_1是系统内置布局,样式就是如下,这部分也可以自己定义布局然后倒入进去,但是只能是一个TextView
代码很少,一看就懂。可能麻烦一些的是泛型这部分,不懂的可以翻翻JAVA的基础。运行效果如下
例子二:这个例子可以增加一个ImageView,但是在设置ArrayAdapter的时候需要增加这个自定义的布局
public ArrayAdapter(Context context,int resource,int textViewResourceId,List<T> objects)
上面的第一个参数是上下文,一般为this。第二个参数是自定义的布局文件,比如下面的就是R.layout.list_item。第三个参数是TextView的id,第四个参数是数据
list_item.xml(main.xml与上面一样)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Activity
package com.loulijun.demo14; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class Demo13Activity extends Activity { private ListView lv; private ArrayList<String> list = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView)findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, R.layout.list_item, R.id.tv, getData()); lv.setAdapter(adapter); } private ArrayList<String> getData() { list.add("180平米的房子"); list.add("一个勤劳漂亮的老婆"); list.add("一辆宝马"); list.add("一个强壮且永不生病的身体"); list.add("一个喜欢的事业"); return list; } }
这里的ArrayAdapter与SimpleAdapter还不一样,它需要在适配器中设置自定义的布局后还要将里面的TextView的id设置进去。但是里面的其他控件比如设置不同的图等就很麻烦实现了,一般如果需要实现
有图片有文字的最好是用BaseAdapter或者SimpleAdaper。ArrayAdapter比较适合于简单的现实一些文字信息
效果如下:
例子三:实现复杂的效果
说实话,这样写的很蛋疼,很多效果不能实现,还是BaseAdapter更加万能,但还是说说如何用ArrayAdapter实现复杂试图。这就需要重写getView方法了,类似BaseAdapter
重写getView方法有很多好处,比如ListView优化的时候主要是在这个方法中的操作进行优化的,另外自定义的视图基本都是通过这个方法来加载,以便达到自己理想的效果
我想显示sd卡的/DCIM/Camera目录中的所有图片到一个列表中,这个列表中的每一项左边是图片的缩略图,右边是文件名。
分析:
这个应用是很典型的 数据绑定 加 自定义显示.
如何搞定?
1. 自定义列表样式
image_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_thumbnail"
android:layout_height="48dip"
android:layout_width="48dip"
/>
<TextView
android:id="@+id/item_file_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingLeft="5dip"
/>
</LinearLayout>
2. 自定义ArrayAdapter
ImageListAdapter
public class ImageListAdapter extends ArrayAdapter<File>{
private int resource;
public ImageListAdapter(Context context, int resourceId, List<File> objects) {
super(context, resourceId, objects);
// 记录下来稍后使用
resource = resourceId;
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout imageListView;
// 获取数据
File file = getItem(position);
String fileName = file.getName();
Bitmap bitmap = getBitmapFromFile(file);
// 系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。
// 当手动完成适配时,必须手动映射数据,这需要重写getView()方法。
// 系统在绘制列表的每一行的时候将调用此方法。
// getView()有三个参数,
// position表示将显示的是第几行,
// covertView是从布局文件中inflate来的布局。
// 我们用LayoutInflater的方法将定义好的image_item.xml文件提取成View实例用来显示。
// 然后将xml文件中的各个组件实例化(简单的findViewById()方法)。
// 这样便可以将数据对应到各个组件上了。
//
if(convertView == null) {
imageListView = new LinearLayout(getContext());
// 看一下android文档中关于LayoutInflater的定义吧
// This class is used to instantiate layout XML file into its corresponding View objects.
// It is never be used directly -- use getLayoutInflater() or getSystemService(String)
// to retrieve a standard LayoutInflater instance that is already hooked up to the current
// context and correctly configured for the device you are running on. . For example:
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);
vi.inflate(resource, imageListView, true);
// 这个每次select images时都被调用
Log.d("Adapter", "convertView is null now");
} else {
// 很奇怪基本没被调用过
imageListView = (LinearLayout)convertView;
Log.d("Adapter", "convertView is not null now");
}
// 填充自定义数据
ImageView imageView = (ImageView) imageListView.findViewById(R.id.item_thumbnail);
TextView textView = (TextView) imageListView.findViewById(R.id.item_file_name);
textView.setText(fileName);
imageView.setImageBitmap(bitmap);
return imageListView;
}
// 从文件获取Bitmap用于填充
private Bitmap getBitmapFromFile(File file) {
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
return bitmap;
}
}
3. 绑定数据
private void bindFilesToList(File[] files) {
List<File> fileList = new ArrayList<File>();
for(File file : files) {
fileList.add(file);
}
ImageListAdapter adapter = new ImageListAdapter(ImageFilesListActivity.this,
R.layout.image_item,
fileList);
setListAdapter(adapter);
}
基本就是这样了