写这篇文章想起葛优做的今麦郎的广告:高一年级的享受,说起方便面,有点饿了。。。本篇就学习Listview更高级的用法,让listview显示文字+图片+按钮事件。
我们需要使用SimpleAdapter,还有继承至BaseAdapter的自定义adapter,先介绍下这两个类:
(1)、impleAdapter
java.lang.Object
↳
android.widget.BaseAdapter
↳
android.widget.SimpleAdapter
Class Overview
An easy adapter to map static data to views defined in an XML file. You can specify the data backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row in the list. The Maps contain the data for each row. You also specify an XML file that defines the views used to display the row, and a mapping from keys in the Map to specific views. Binding data to views occurs in two phases. First, if a SimpleAdapter.ViewBinder is available, setViewValue(android.view.View, Object, String) is invoked. If the returned value is true, binding has occurred. If the returned value is false, the following views are then tried in order:
$1__VE_ITEM__$1__VE_ITEM__· A view that implements Checkable (e.g. CheckBox). The expected bind value is a boolean.
$1__VE_ITEM__$1__VE_ITEM__· TextView. The expected bind value is a string and setViewText(TextView, String) is invoked.
$1__VE_ITEM__$1__VE_ITEM__· ImageView. The expected bind value is a resource id or a string and setViewImage(ImageView, int) or setViewImage(ImageView, String) is invoked.
If no appropriate binding can be found, an IllegalStateException is thrown.
(2)、BaseAdapter
java.lang.Object
↳
android.widget.BaseAdapter
$2$2Known Direct Subclasses
ArrayAdapter<T>, CursorAdapter, SimpleAdapter
ArrayAdapter<T>
A concrete BaseAdapter that is backed by an array of arbitrary objects.
CursorAdapter
Adapter that exposes data from a Cursor to a ListView widget.
SimpleAdapter
An easy adapter to map static data to views defined in an XML file.
$2Known Indirect Subclasses
ResourceCursorAdapter, SimpleCursorAdapter
ResourceCursorAdapter
An easy adapter that creates views defined in an XML file.
SimpleCursorAdapter
An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file.
Class Overview
Common base class of common implementation for an Adapter that can be used in both ListView (by implementing the specialized ListAdapter interface} and Spinner (by implementing the specialized SpinnerAdapter interface.
开始我们的范例:
我们这个范例做的是一个网上商城的水果列表页面,用户可以浏览商品图片,描述,然后点击按钮可以购买
第一步:新建页面lv.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_marginTop="22dp" android:id="@+id/imgProduct"></ImageView>
<TextView android:id="@+id/tvTitle" android:text="商品名" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/imgProduct" android:layout_toRightOf="@+id/imgProduct"></TextView>
<TextView android:id="@+id/tvDescription" android:text="详细描述" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/imgProduct" android:layout_alignLeft="@+id/tvTitle"></TextView>
<Button android:id="@+id/buttonbuy" android:layout_width="wrap_content" android:text="@string/buy" android:layout_height="wrap_content" android:layout_below="@+id/imgProduct" android:layout_alignParentLeft="true"></Button>
</RelativeLayout>
第二步:新建自定义容器MyAdapter.java
/**
*
*/
package Test.HelloWorld;
import java.util.List;
import java.util.Map;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @author zhuzhifei
*
*/
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
List<Map<String, Object>> newData;
Context newContext;
// 自定义构造函数
public MyAdapter(Context context, List<Map<String, Object>> mData) {
newContext = context;
newData = mData;
this.mInflater = LayoutInflater.from(context);
}
/*
* (non-Javadoc)
*
* @see android.widget.Adapter#getCount()
*/
@Override
public int getCount() {
// TODO Auto-generated method stub
return newData.size();
}
/*
* (non-Javadoc)
*
* @see android.widget.Adapter#getItem(int)
*/
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
/*
* (non-Javadoc)
*
* @see android.widget.Adapter#getItemId(int)
*/
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
/*
* (non-Javadoc)
*
* @see android.widget.Adapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
//从xml页面实例化视图
convertView = mInflater.inflate(R.layout.lv, null);
//填充我们定义的容器里面的控件
holder.img = (ImageView) convertView.findViewById(R.id.imgProduct);
holder.title = (TextView) convertView.findViewById(R.id.tvTitle);
holder.info = (TextView) convertView
.findViewById(R.id.tvDescription);
holder.viewBtn = (Button) convertView.findViewById(R.id.buttonbuy);
//Tags can also be used to store data within a view without resorting to another data structure.
convertView.setTag(holder);
} else {
//直接从视图里面获取控件容器
holder = (ViewHolder) convertView.getTag();
}
//将数据源中的数据填充到每一行中对应的控件
holder.img.setBackgroundResource((Integer) newData.get(position).get(
"img"));
holder.title.setText((String) newData.get(position).get("title"));
holder.info.setText((String) newData.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;
}
/**
*
* listview中点击按键弹出对话框
*/
public void showInfo() {
new AlertDialog.Builder(newContext).setTitle("提示")
.setMessage("购买成功!")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
第三步:新建Activity, LvActivity.java
/**
*
*/
package Test.HelloWorld;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
/**
* @author zhuzhifei
*
*/
public class LvActivity extends ListActivity {
private List<Map<String, Object>> mData;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mData=getData();
//第一种方法,使用SimpleAdapter显示文字和图片
// SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.lv,
// new String[]{"title","info","img"},
// new int[]{R.id.tvTitle,R.id.tvDescription,R.id.imgProduct});
// setListAdapter(adapter);
//第二种方法,使用自定义Adapter
MyAdapter adapter = new MyAdapter(this, mData);
setListAdapter(adapter);
}
//数据源,这些数据其实可以用xml文件来配置,这里就先模拟一些
private List<Map<String, Object>> getData() {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", "苹果");
map.put("info", "平平安安的苹果,6元每公斤");
map.put("img", R.drawable.apple);
list.add(map);
map = new HashMap<String, Object>();
map.put("title", "西瓜");
map.put("info", "好吃的西瓜,2元每公斤");
map.put("img", R.drawable.watermelon);
list.add(map);
map = new HashMap<String, Object>();
map.put("title", "香蕉");
map.put("info", "润肠香蕉,5元每公斤");
map.put("img", R.drawable.banana);
list.add(map);
map = new HashMap<String, Object>();
map.put("title", "红提");
map.put("info", "香甜可口的红提,16元每公斤");
map.put("img", R.drawable.grape);
list.add(map);
return list;
}
}
第四步:AndroidManifest.xml里面加入我们的Activity
<activity android:name=".LvActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
第五步:运行效果