Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.而android 提供了几种Adapter:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.
根据数据来源形式的不同可以选择不同的Adapter,比如数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于通过查询数据库获得Cursor那就使用SimpleCursorAdapter.
使用simpleadapter的例子:
主布局文件
xml version ="1.0" encoding ="utf-8" ?>
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation ="vertical"
android:layout_width ="fill_parent"
android:layout_height ="fill_parent"
>
< RelativeLayout
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
>
< Spinner
android:id ="@+id/subway_lines"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content" >
Spinner >
< TextView
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:layout_below ="@id/subway_lines"
android:layout_alignLeft ="@id/subway_lines"
android:id ="@+id/select_line"
/>
RelativeLayout >
< ListView
android:layout_width ="fill_parent"
android:layout_height ="fill_parent"
android:id ="@+id/station_listView"
/>
LinearLayout >
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 ="fill_parent" >
< TextView
android:layout_width ="200px"
android:layout_height ="fill_parent"
android:textSize ="20px"
android:gravity ="center_horizontal"
android:id ="@+id/station_name"
/>
< TextView
android:layout_width ="200px"
android:layout_height ="fill_parent"
android:layout_toRightOf ="@id/station_name"
android:textSize ="20px"
android:layout_alignTop ="@id/station_name"
android:id ="@+id/station_info"
/>
RelativeLayout >
import java.util.ArrayList;
public class SubwayActivity extends Activity {
private static final String TAG = "SubwayActivity";
private SubwayService subwayService;
private TextView selectLine;
private Spinner subwayLines;
private ArrayAdapter linesAdapter;
private List linesNames;
private ListView stationListView;
private SimpleAdapter stationsAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stationListView = (ListView) findViewById(R.id.station_listView);
subwayService = new SubwayService( this);
//初始化数据
// subwayService.init();
List listLines = subwayService.getLineScrollData();
linesNames = new ArrayList();
for (SubwayLine subwayLine : listLines) {
linesNames.add(subwayLine.getLineName());
}
// 第一步:添加一个下拉列表项的list,这里添加的项就是下拉列表的菜单项
selectLine = (TextView) findViewById(R.id.select_line);
subwayLines = (Spinner) findViewById(R.id.subway_lines);
// 第二步:为下拉列表定义一个适配器,这里就用到里前面定义的list。
linesAdapter = new ArrayAdapter(
this, android.R.layout.simple_spinner_item,linesNames);
// 第三步:为适配器设置下拉列表下拉时的菜单样式。
linesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// 第四步:将适配器添加到下拉列表上
subwayLines.setAdapter(linesAdapter);
//第五步:为下拉列表设置各种事件的响应,这个事响应菜单被选中
subwayLines.setOnItemSelectedListener(selectedListener);
/*下拉菜单弹出的内容选项触屏事件处理*/
subwayLines.setOnTouchListener(onTouchListener);
/*下拉菜单弹出的内容选项焦点改变事件处理*/
subwayLines.setOnFocusChangeListener(onFocusChangeListener);
}
/**
* 为下拉列表设置各种事件的响应,这个事响应菜单被选中
*/
private OnItemSelectedListener selectedListener = new Spinner.OnItemSelectedListener(){
@SuppressWarnings( "unchecked")
public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) {
String lineName = linesAdapter.getItem(arg2);
SubwayLine line = subwayService.findLine(lineName);
/*根据lineId查询出stations*/
List stations = subwayService.getStationLineScrollData(line.getLineId());
/*把stations的属性值放到List>中*/
List> data =
new ArrayList>();
for (SubwayStation station : stations) {
HashMap map =
new HashMap();
if(station.getIsChange() == 1){
map.put( "stationName", station.getStationName());
List changeStations = subwayService.getChangeStationExceptThis(station.getStationName(), line.getLineId());
StringBuilder builder = new StringBuilder();
builder.append( "换乘 ");
if(changeStations != null && changeStations.size() > 0){
for (SubwayStation changeStation : changeStations) {
SubwayLine changeLine = subwayService.findLine(changeStation.getLineId());
builder.append(changeLine.getLineName()).append( ",");
}
builder.deleteCharAt(builder.length()-1);
}
map.put( "stationInfo",builder.toString());
} else{
map.put( "stationName", station.getStationName());
map.put( "stationInfo", station.getStationInfo());
}
data.add(map);
}
/*设置stationsAdapter适配器*/
stationsAdapter = new SimpleAdapter(
SubwayActivity. this,
data,
R.layout.stationitem,
new String[] { "stationName", "stationInfo" },
new int[] { R.id.station_name, R.id.station_info });
stationListView.setAdapter(stationsAdapter);
/* 将所选mySpinner 的值带入myTextView 中*/
selectLine.setText( "以下是:"+ lineName + " 车站列表...");
/* 将mySpinner 显示*/
arg0.setVisibility(View.VISIBLE);
}
@SuppressWarnings( "unchecked")
public void onNothingSelected(AdapterView arg0) {
selectLine.setText("");
arg0.setVisibility(View.VISIBLE);
}
};
/**
* 下拉菜单弹出的内容选项触屏事件处理
*/
private OnTouchListener onTouchListener = new Spinner.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
/* 将mySpinner 隐藏,不隐藏也可以,看自己爱好*/
// v.setVisibility(View.INVISIBLE);
return false;
}
};
/**
* 下拉菜单弹出的内容选项焦点改变事件处理
*/
private OnFocusChangeListener onFocusChangeListener = new Spinner.OnFocusChangeListener(){
public void onFocusChange(View v, boolean hasFocus) {
v.setVisibility(View.VISIBLE);
}
};
}
public class SubwayActivity extends Activity {
private static final String TAG = "SubwayActivity";
private SubwayService subwayService;
private TextView selectLine;
private Spinner subwayLines;
private ArrayAdapter
private List
private ListView stationListView;
private SimpleAdapter stationsAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stationListView = (ListView) findViewById(R.id.station_listView);
subwayService = new SubwayService( this);
//初始化数据
// subwayService.init();
List
linesNames = new ArrayList
for (SubwayLine subwayLine : listLines) {
linesNames.add(subwayLine.getLineName());
}
// 第一步:添加一个下拉列表项的list,这里添加的项就是下拉列表的菜单项
selectLine = (TextView) findViewById(R.id.select_line);
subwayLines = (Spinner) findViewById(R.id.subway_lines);
// 第二步:为下拉列表定义一个适配器,这里就用到里前面定义的list。
linesAdapter = new ArrayAdapter
// 第三步:为适配器设置下拉列表下拉时的菜单样式。
linesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// 第四步:将适配器添加到下拉列表上
subwayLines.setAdapter(linesAdapter);
//第五步:为下拉列表设置各种事件的响应,这个事响应菜单被选中
subwayLines.setOnItemSelectedListener(selectedListener);
/*下拉菜单弹出的内容选项触屏事件处理*/
subwayLines.setOnTouchListener(onTouchListener);
/*下拉菜单弹出的内容选项焦点改变事件处理*/
subwayLines.setOnFocusChangeListener(onFocusChangeListener);
}
/**
* 为下拉列表设置各种事件的响应,这个事响应菜单被选中
*/
private OnItemSelectedListener selectedListener = new Spinner.OnItemSelectedListener(){
@SuppressWarnings( "unchecked")
public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) {
String lineName = linesAdapter.getItem(arg2);
SubwayLine line = subwayService.findLine(lineName);
/*根据lineId查询出stations*/
List
/*把stations的属性值放到List
List
for (SubwayStation station : stations) {
HashMap
if(station.getIsChange() == 1){
map.put( "stationName", station.getStationName());
List
StringBuilder builder = new StringBuilder();
builder.append( "换乘 ");
if(changeStations != null && changeStations.size() > 0){
for (SubwayStation changeStation : changeStations) {
SubwayLine changeLine = subwayService.findLine(changeStation.getLineId());
builder.append(changeLine.getLineName()).append( ",");
}
builder.deleteCharAt(builder.length()-1);
}
map.put( "stationInfo",builder.toString());
} else{
map.put( "stationName", station.getStationName());
map.put( "stationInfo", station.getStationInfo());
}
data.add(map);
}
/*设置stationsAdapter适配器*/
stationsAdapter = new SimpleAdapter(
SubwayActivity. this,
data,
R.layout.stationitem,
new String[] { "stationName", "stationInfo" },
new int[] { R.id.station_name, R.id.station_info });
stationListView.setAdapter(stationsAdapter);
/* 将所选mySpinner 的值带入myTextView 中*/
selectLine.setText( "以下是:"+ lineName + " 车站列表...");
/* 将mySpinner 显示*/
arg0.setVisibility(View.VISIBLE);
}
@SuppressWarnings( "unchecked")
public void onNothingSelected(AdapterView arg0) {
selectLine.setText("");
arg0.setVisibility(View.VISIBLE);
}
};
/**
* 下拉菜单弹出的内容选项触屏事件处理
*/
private OnTouchListener onTouchListener = new Spinner.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
/* 将mySpinner 隐藏,不隐藏也可以,看自己爱好*/
// v.setVisibility(View.INVISIBLE);
return false;
}
};
/**
* 下拉菜单弹出的内容选项焦点改变事件处理
*/
private OnFocusChangeListener onFocusChangeListener = new Spinner.OnFocusChangeListener(){
public void onFocusChange(View v, boolean hasFocus) {
v.setVisibility(View.VISIBLE);
}
};
}
/*设置stationsAdapter适配器*/
stationsAdapter = new SimpleAdapter(
SubwayActivity. this,
data,
R.layout.stationitem,
new String[] { "stationName", "stationInfo" },
new int[] { R.id.station_name, R.id.station_info });
stationListView.setAdapter(stationsAdapter);
stationsAdapter = new SimpleAdapter(
SubwayActivity. this,
data,
R.layout.stationitem,
new String[] { "stationName", "stationInfo" },
new int[] { R.id.station_name, R.id.station_info });
stationListView.setAdapter(stationsAdapter);
===========================================================
以上是简单的使用adapter的方法,一般情况下这样就够用了.接下来是自定义adapter.
继承BaseAdapter,重写四个方法.
public
class WeatherAdapter
extends BaseAdapter {
private Context context;
private List weatherList;
//这就是adapter关联的List,用来存储数据.还记的ArrayList
public WeatherAdapter(Context context, List weatherList ) {
this.context = context;
this.weatherList = weatherList;
}
public int getCount() {
return weatherList.size();
}
public Object getItem( int position) {
return weatherList.get(position);
}
public long getItemId( int position) {
return position;
}
public View getView( int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
return new WeatherAdapterView( this.context, weather );
}
}
private Context context;
private List
public WeatherAdapter(Context context, List
this.context = context;
this.weatherList = weatherList;
}
public int getCount() {
return weatherList.size();
}
public Object getItem( int position) {
return weatherList.get(position);
}
public long getItemId( int position) {
return position;
}
public View getView( int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
return new WeatherAdapterView( this.context, weather );
}
}
自定义的View
class WeatherAdapterView
extends LinearLayout {
public static final String LOG_TAG = "WeatherAdapterView";
public WeatherAdapterView(Context context,
Weather weather ) {
super( context );
this.setOrientation(HORIZONTAL);
LinearLayout.LayoutParams cityParams =
new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT);
cityParams.setMargins(1, 1, 1, 1);
TextView cityControl = new TextView( context );
cityControl.setText( weather.getCity() );
addView( cityControl, cityParams);
LinearLayout.LayoutParams temperatureParams =
new LinearLayout.LayoutParams(20, LayoutParams.WRAP_CONTENT);
temperatureParams.setMargins(1, 1, 1, 1);
TextView temperatureControl = new TextView(context);
temperatureControl.setText( Integer.toString( weather.temperature ) );
addView( temperatureControl, temperatureParams);
LinearLayout.LayoutParams skyParams =
new LinearLayout.LayoutParams(25, LayoutParams.WRAP_CONTENT);
ImageView skyControl = new ImageView( context );
Log.d( LOG_TAG, weather.getCity()+ " -> "+weather.sky );
skyControl.setImageResource( weather.getSkyResource() );
addView( skyControl, skyParams );
}
}
public static final String LOG_TAG = "WeatherAdapterView";
public WeatherAdapterView(Context context,
Weather weather ) {
super( context );
this.setOrientation(HORIZONTAL);
LinearLayout.LayoutParams cityParams =
new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT);
cityParams.setMargins(1, 1, 1, 1);
TextView cityControl = new TextView( context );
cityControl.setText( weather.getCity() );
addView( cityControl, cityParams);
LinearLayout.LayoutParams temperatureParams =
new LinearLayout.LayoutParams(20, LayoutParams.WRAP_CONTENT);
temperatureParams.setMargins(1, 1, 1, 1);
TextView temperatureControl = new TextView(context);
temperatureControl.setText( Integer.toString( weather.temperature ) );
addView( temperatureControl, temperatureParams);
LinearLayout.LayoutParams skyParams =
new LinearLayout.LayoutParams(25, LayoutParams.WRAP_CONTENT);
ImageView skyControl = new ImageView( context );
Log.d( LOG_TAG, weather.getCity()+ " -> "+weather.sky );
skyControl.setImageResource( weather.getSkyResource() );
addView( skyControl, skyParams );
}
}
最后在Activity中使用
public
class CustomAdapterActivity
extends ListActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList weatherList =
new ArrayList();
Weather w = new Weather( "London", 17, Weather.OVERCAST );
weatherList.add( w );
w = new Weather( "Paris", 22, Weather.OVERCAST );
weatherList.add( w );
w = new Weather( "Athens", 29, Weather.SUNNY );
weatherList.add( w );
w = new Weather( "Stockholm", 12, Weather.RAIN );
weatherList.add( w );
WeatherAdapter weatherAdapter = new WeatherAdapter(
this,
weatherList );
setListAdapter( weatherAdapter );
}
}
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList
Weather w = new Weather( "London", 17, Weather.OVERCAST );
weatherList.add( w );
w = new Weather( "Paris", 22, Weather.OVERCAST );
weatherList.add( w );
w = new Weather( "Athens", 29, Weather.SUNNY );
weatherList.add( w );
w = new Weather( "Stockholm", 12, Weather.RAIN );
weatherList.add( w );
WeatherAdapter weatherAdapter = new WeatherAdapter(
this,
weatherList );
setListAdapter( weatherAdapter );
}
}
===========================================================
再就是Adapter的优化,一个广为流传的 ViewHolder、ViewCache办法:
public View getView(
int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.topic_list, null);
holder.title = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
}
public class ViewHolder {
public TextView getTitle() {
if (title == null) {
title = (TextView) baseView.findViewById(R.id.title);
}
return title;
}
}
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.topic_list, null);
holder.title = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
}
public class ViewHolder {
public TextView getTitle() {
if (title == null) {
title = (TextView) baseView.findViewById(R.id.title);
}
return title;
}
}
或者使用HashMap做缓存的方法:
HashMap m =
new HashMap();
public View getView( int position, View view, ViewGroup parent) {
View convertView = m.get(position);
if (convertView != null) {
return convertView;
} else {
convertView = inflater.inflate(R.layout.topic_list, null);
TextView title = (TextView) convertView.findViewById(R.id.title);
m.put(position, convertView);
}
}
public View getView( int position, View view, ViewGroup parent) {
View convertView = m.get(position);
if (convertView != null) {
return convertView;
} else {
convertView = inflater.inflate(R.layout.topic_list, null);
TextView title = (TextView) convertView.findViewById(R.id.title);
m.put(position, convertView);
}
}