原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://lichen.blog.51cto.com/697816/492200 Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.而android 提供了几种Adapter:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter. 根据数据来源形式的不同可以选择不同的Adapter,比如数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于通过查询数据库获得Cursor那就使用SimpleCursorAdapter. 使用simpleadapter的例子: 主布局文件 <!-- main.xml-->
<? 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 > 然后是ListView布局 <!-- stationitem.xml-->
<? 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 > 接下来是Activity 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<String> linesAdapter;
private List<String> 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<SubwayLine> listLines = subwayService.getLineScrollData();
linesNames = new ArrayList<String>();
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<String>( 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<SubwayStation> stations = subwayService.getStationLineScrollData(line.getLineId());
/*把stations的属性值放到List<HashMap<String, String>>中*/
List<HashMap<String, String>> data = newArrayList<HashMap<String, String>>();
for (SubwayStation station : stations) {
HashMap<String, String> map = new HashMap<String, String>();
if(station.getIsChange() == 1){
map.put( "stationName", station.getStationName());
List<SubwayStation> 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);
}
};
} 其中,核心的是 /*设置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<Weather> weatherList; //这就是adapter关联的List,用来存储数据.还记的ArrayList

public WeatherAdapter(Context context, List<Weather> 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 );
}

}
自定义的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 );
}
}
最后在Activity中使用 public class CustomAdapterActivity extends ListActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<Weather> weatherList = new ArrayList<Weather>();
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;
}
}
或者使用HashMap做缓存的方法: HashMap<Integer, View> m = new HashMap<Integer, View>();

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);
}
} 来自:http://www.eoeandroid.com/thread-56717-1-1.html
Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.而android 提供了几种Adapter:ArrayAdapter<T>, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.我猜想这些Adapter的区别在于你的数据来源不一样:比如若你的数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于通过查询数据库获得Cursor那就使用SimpleCursorAdapter等。就目前我经常使用的BaseAdapter和SimpleCursorAdapter。


1,BaseAdapter:---数据来源于Arraylist-->MyArraylist
当你继承BaseAdapter客制化你的Adapter时,你必须OverWrite以下函数:
Java代码
@Override
public int getCount() {
// TODO Auto-generated method stub
System.out.println("the size is\t" + MyArraylist.size());
return MyArraylist.size();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
System.out.println("the size is\t" + MyArraylist.size());
return MyArraylist.size();
}
getCount返回的就是你的有多少条数据需要绑定的,也就是需要多少个View.比如这里返回的就是MyArraylist的Size.

Java代码
public View getView(int position, View v, ViewGroup parent) {
// TODO Auto-generated method stub

View view;
if (v == null) {
view = mInflater.inflate(R.layout.track_list_item, null);
} else {
view = v;
}}
public View getView(int position, View v, ViewGroup parent) {
// TODO Auto-generated method stub
View view;
if (v == null) {
view = mInflater.inflate(R.layout.track_list_item, null);
} else {
view = v;
}}

通过getView就获得了view来显示数据了。在这里你就可以自定义你的View了,但你通过XML定义可以通过LayoutInflater来inflater你的XML。getView里面就可以将MyArraylist的数据通过position 这个来将数据一条绑定一个View了。


2,SimpleCursorAdapter:---数据来源于数据库--->MyCursor
要实现bindView()和newView()这两个抽象方法需要实现的内容。

public void bindView(View view, Context context, Cursor cursor),重用一个已有的view,使其显示当前cursor所指向的数据。

public View newView(Context context, Cursor cursor, ViewGroup parent),为cursor所指向的数据新建一个View对象,并显示其数据。

通俗的说:比如你一个listview在一个屏幕里一次只能显示8条数据,那么第一次显示的时候就会newView 8次生成8个View,调用bindView绑定8条数据,而你有16条数据,但你拖动滚动条看9-16条时,此时不会再调用newView了,而只能调用了bindView去绑定新的数据而了。这样就省了空间了。


注意:传入到CursorAdapter中的Cursor结果集必须包含有列名为_id的列,否则SimpleCursorAdapter将不会起作用。

对于SimpleCursorAdapter中的newView与bindView的作用在BaseAdapter中的getView中也有这样的意义:getView里面我们必须做判断才能达到这种效果,就是要判断第二个参数View的是否为空:当空时就Infalte新的View,但不为空时就要就用它,这样就第一屏幕Infate 8个View,后面就直接使用这个8个view了。

注意:getView中是返回一个view,必须返回的是你infalte之后不为空的View,不然会报空指针异常

更多相关文章

  1. Android文件管理器与media数据库的同步问题
  2. android异步向服务器请求数据
  3. Android使用Bundle进行数据传递分析
  4. Android里监视数据库的变化 registerContentObserver 接口
  5. Android下的数据储存方式(三)
  6. android中将数据写入手机内存和sdcard中的文件
  7. Android settings.db数据库中添加一条新的默认配置项
  8. Android之解析Json数据

随机推荐

  1. Android移动应用开发基础2003291341
  2. Android应用开发提高系列(4)――Android动
  3. 学习Android从0开始之ActionBar(活动条)之
  4. Android(安卓)使用意图播放本地视频
  5. Android(安卓)TextView setText卡顿问题
  6. Android Dev Guide -> User Interface
  7. Android手机的那点事
  8. Gartner:Android将在2012年成为第二大手
  9. 20172323 2017-2018-2《程序设计与数据结
  10. android 通过局域网udp广播自动建立socke