2012/05/22

ListViewのカスタマイズ

ListViewをカスタマイズして使う際、パフォーマンス的な観点からAdapterクラスのgetView()メソッド内ではView(convertView)の再利用が推奨されています。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
 if (convertView==null ) {
  convertView = inflater.inflate(R.layout.xxxxxx, null);
 }
 //データをセットする処理など

    return convertView;
}

一般的にListViewは同じビューを繰り返し表示させて使う為、ビューの再利用は上記で良いのですが、データの内容によってビューがコロコロ変わる様な使い方をすると、渡されたビューが使いたいビューと異なり、NullPointerException等の問題が発生する場合があります(アクセスしようとした子ビューが無い等の理由で)

そのような時はinflateするレイアウトにidを付与しておき、渡されたビューが同じかどうかの判断材料として使います。
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  //これはリストビューに表示するデータを表現したクラスです
  JobProcess item = (JobProcess) getItem(position);
  //データのタイプに合わせてビューを準備する  
  switch (item.getType()) {
  case JobProcess.SUBTITLE:
   if (convertView==null || convertView.getId()!=R.id.subtitle ) {
    convertView = inflater
      .inflate(R.layout.contents_subtitle, null);
   }
   TextView tvSubTitle = (TextView) convertView
     .findViewById(R.id.textSubTitle);
   tvSubTitle.setText(item.getProcessText());
   break;

  case JobProcess.PROCESS:
   if ( convertView==null || convertView.getId()!=R.id.process) {
    convertView = inflater.inflate(R.layout.contents_process, null);
   }
   TextView tvCNO = (TextView) convertView.findViewById(R.id.tvCNO);
   tvCNO.setText(item.getProcessNo());
   TextView tvProcText = (TextView) convertView
     .findViewById(R.id.tvProcText);
   tvProcText.setText(item.getProcessText());
   break;
  default:
   
   break;
  }

  return convertView;
 }

Tagを利用してない場合はそこに何か目印を付けるのもアリだと思います。
  case JobProcess.NOTES:
   //
    if (convertView==null || !convertView.getTag().equals("notes")) {
        convertView = inflater.inflate(R.layout.contents_notes, null);
        //タグに目印をセット
        convertView.setTag("notes");
    }
    TextView tvNotes = (TextView) convertView.findViewById(R.id.tvNotes);
    tvNotes.setText(item.getProcessText());
 
  break;

しかしビューを何種類も用意すると、データの『並び方』によっては再利用率がぐっと落ちますね。今自分が作ってるアプリではリストビューをスクロール(=ビューが再利用される)するほどデータ量が無いので良いと思うのですが。


0 件のコメント:

コメントを投稿