Android Adapter使用の詳細

13028 ワード

Adapterは、ListView,GridView,Galleryにデータを埋め込むなど、データの埋め込みを支援するための中間ブリッジです.androidはいくつかのAdapterを提供している:ArrayAdapter,BaseAdapter,CursorAdapter,HeaderView ListAdapter,ListAdapter,ResourceCursorAdapter,SimpleAdapter,SimpleCursorAdapter,SpinnerAdapter,WrapperListAdapter.
データソースの形式によって異なるAdapterを選択することができる、例えば、データソースが1つのArraylistからBaseAdapter、SimpleAdapterを使用し、データソースがクエリーデータベースを通じてCursorを得るからSimpleCursorAdapterを使用する.
simpleadapterを使用する例:
メインレイアウトファイル:



        
         
         
         
     
    

次にListViewレイアウト



     
     

次は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 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);
    }
  };
}

  ,    
 /*  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を継承し、4つの方法を書き換える.
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 );
        }

}

カスタムビュー
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 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 );
        }
}

さらにAdapterの最適化は、広く伝えられているView Holder、View Cacheの方法です.
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 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);
  }
}