安卓 Adapter 使用详解

来源:互联网 发布:discuz自动回帖软件 编辑:程序博客网 时间:2024/05/16 05:17
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 = new    ArrayList<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);  }}



原创粉丝点击