| 
          
         | 
         
          
          
          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); 
  } 
} |  
   
          
          
          
            
  
            [这个贴子最后由 flybird 在 2020-04-18 16:45:10 重新编辑]
          
          
         | 
        
      
 
          |