参考资料:
《第一行代码》第二版
Android Adapter:ArrayAdapter篇
默认情况下,ArrayAdapter期望布局文件里只有一个TextView,连Layout都不能包含(构造方法1、3、5)。
如果你想使用复杂的布局,需要向向构造函数传递一个filed id
,即布局中对应TextView的id。
如果想使用更复杂的布局,就要重写BaseAdapter的getView(int, View, ViewGroup)
方法返回你需要的View。
ArrayAdapter有六个构造函数,前5种都是调用最后一个构造函数形成的。
//1
ArrayAdapter(Context context, int resource)
//2
ArrayAdapter(Context context, int resource, int textViewResourceId)
//3
ArrayAdapter(Context context, int resource, T[] objects)
//4
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
//5
ArrayAdapter(Context context, int resource, List objects)
//6
ArrayAdapter(Context context, int resource, int textViewResourceId, Lis objects)
默认情况下,ArrayAdapter期望布局文件里只有一个TextView,连Layout都不能包含(构造方法1、3、5)
ArrayAdapter的最简单使用需要调用构造函数1、3、5,传入一个TextView布局和一个数组即可。
activity_main.xml的布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
ListView>
LinearLayout>
MainActivity中的代码:
public class MainActivity extends AppCompatActivity {
private String[] data = {"Apple", "Banana", "Orange", "Watermelon","Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//android.R.layout.simple_list_item_1是Android内置的布局文件,里面只有一个TextView,用来展示一段文本
ArrayAdapter adapter = new ArrayAdapter (
MainActivity.this, android.R.layout.simple_list_item_1, data);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
}
显示效果如下:
ArrayAdapter的进阶使用需要调用构造函数2、4、6中的一种,只需要自定义一个包含TextView的布局,将布局id和TextView的id传递给ArrayAdapter即可。
这里要自定义一个包含TextView的布局custom_list_item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/custom_textView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"/>
LinearLayout>
将下面的代码
ArrayAdapter adapter = new ArrayAdapter (
MainActivity.this, android.R.layout.simple_list_item_1, data);
替换为
ArrayAdapter adapter = new ArrayAdapter (
MainActivity.this, R.layout.custom_list_item, R.id.custom_textView, data);
其中,custom_list_item为自定义的布局,custom_textView是包含在custom_list_item中的TextView的id。
显示效果如下:
继承ArrayAdapter来自定义自己需要的Adapter,只需要重写getView(int,View,ViewGroup)
方法就可以实现复杂布局的效果,其余的和前面没有区别。
getView
View getView(int position, View convertView, ViewGroup parent)
convertView用于将之前加载好的布局进行缓存
这里的布局仍然采用前面的自定义布局。
不过,图片是在代码中添加的,所以删除布局文件中添加图片的代码android:src="@mipmap/ic_launcher"
,其他的保持不变。
自定义Adapter
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
resourceId = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);//获取当前项的Fruit实例
View view;
ViewHolder viewHolder;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
viewHolder = new ViewHolder();
viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_iamge);
viewHolder.fruitName = (TextView) view.findViewById(R.id.custom_textView);
view.setTag(viewHolder);//将ViewHolder存储在View中
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();//重新获取ViewHolder
}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;
}
class ViewHolder {
ImageView fruitImage;
TextView fruitName;
}
}
Fruit实体类
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private List fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
FruitAdapter adapter = new FruitAdapter (
MainActivity.this,R.layout.custom_list_item, fruitList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
//为ListView设置点击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view,
int position, long id) {
Fruit fruit = fruitList.get(position);
Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
}
private void initFruits() {
Fruit apple = new Fruit("Apple", R.mipmap.ic_launcher);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.mipmap.ic_launcher);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.mipmap.ic_launcher);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.mipmap.ic_launcher);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.mipmap.ic_launcher);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.mipmap.ic_launcher);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.mipmap.ic_launcher);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("Strawberry", R.mipmap.ic_launcher);
fruitList.add(strawberry);
Fruit cherry = new Fruit("Cherry", R.mipmap.ic_launcher);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.mipmap.ic_launcher);
fruitList.add(mango);
}
}