Re: ListViewに詰めたCheckBoxが認識できない

294 views
Skip to first unread message

天然パーマ

unread,
Apr 23, 2013, 4:53:50 AM4/23/13
to android-g...@googlegroups.com, j...@swrmt.sakura.ne.jp
天然パーマと申します。

昔作ったメモにチェックボックス付きのリストビューがありました。
onCheckedChangedにてgetItemから1レコード分の情報を取得しないとうまく更新ができなかった記憶があります。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
holder.inCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
        ListViewArrayAdapterData data =getItem(position); <-- ここの部分
        data.checkBoxChecked = arg1;
    }
});
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

> 前後の行のキャッシュが効いてしまっているせいか、
> チェックがついてはいけない所でついたりしてしまいます。
これに関しては、convertViewの再利用する際に違う箇所にデータを入力しています。
convertView.getTag()を使用すれば防げるはずです。
if(convertView == null) {
各処理
} else {
holder = convertView.getTag(); <-- ここ
}


作り方はGoogleIOをベースにしています。
ListViewについて詳しく書かれているのでリンクを張っておきます。



2013年4月15日月曜日 16時43分52秒 UTC+9 Funa:
AndroidSDK1.7で開発しています。
 
まだまだかじり始めたばかりの初心者です。
WEB上でも同様の現象が報告され、それを元に下記のように組んだのですが、
NullPointerExceptionで正しく動きません。
 
AlertDialogにListViewを埋め込み、下記が表示レイアウト部です。
 
◆ソース
 //設定値保存用
 public boolean[] check;
.........................
 private class DialogAdapter extends BaseAdapter {
  //セルのビューの生成
  @Override
  public View getView(int idx, View convertView, ViewGroup parent) {
   Context context=Main.this;
   AdapterItem item=list.get(idx);
 
   //レイアウトの生成
   if (convertView==null) {
          LinearLayout layout=ApUtil.makeLinearLayout(context,Color.rgb(0,0,0),0,0,0,0,null);
    convertView=layout;
 
    //チェックボックスの生成
    CheckBox checkBox=new CheckBox(context);
    //checkBox.setId(tag);//これをキーにlistのchkの値を切り替える
    checkBox.setTag(idx);//これをキーにlistのchkの値を切り替える
    checkBox.setBackgroundResource(R.drawable.checkbox_background);//カスタムスタイル
    checkBox.setButtonDrawable(R.drawable.checkbox);//カスタムスタイル
    layout.addView(checkBox, new LinearLayout.LayoutParams(30,38));
    //checkBox.setOnClickListener(mCheckBoxListener);
 
    //アイコンスタイル
    ImageView imageView=new ImageView(context);
    imageView.setTag("icon1");
    layout.addView(imageView);
 
    //テキストスタイル
    TextView textView=new TextView(context);
    textView.setTag("text2");
    layout.addView(textView);
   }
   //※ここで値をセットしないとViewのキャッシュが効いてスクロール時に正しく表示されない
   ((TextView)convertView.findViewWithTag("text2")).setText(item.text2);         ←①
   ((ImageView)convertView.findViewWithTag("icon1")).setImageBitmap(item.icon1);     ←②
   
   CheckBox chk = (CheckBox)convertView.findViewWithTag(idx);               ←③
   final int p = idx;
   chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
     // チェックボックスのチェック状態を保持
     check[p] = isChecked;
    }
   });
   chk.setChecked(check[idx]);
   
   return convertView;
  }
}
....................
// チェックボックスのリスナー
View.OnClickListener mCheckBoxListener = new View.OnClickListener() {
 @Override
 public void onClick(View v) {
  CheckBox checkBox = (CheckBox) v;
  // チェックボックスのチェック状態を保持
  check[Integer.parseInt(String.valueOf(checkBox.getTag()))] = checkBox.isChecked();
 }
};
 
問題は、上記の③に当たるのですが、①②はタグを認識し必ずコントロールを取得できるのですが、
CheckBoxをtagで検索しても認識できない場合があります。
(Idでもやってみたのですが、結果は同じでした。)
 
「if(chk !=null)」でExceptionを回避する事は可能ですが、前後の行のキャッシュが効いてしまっているせいか、
チェックがついてはいけない所でついたりしてしまいます。
①②と同様に一度表示したCheckBoxがnull取得してはいけないんだと思います。
 
Holderクラスを生成したやり方も紹介されていたのですが、どうしてもCheckBoxがnullになってしまう事が
根本的な問題でうまく行きませんでした。
 
「(CheckBox)convertView.findViewWithTag」のように必ず取得する方法は何か無いでしょうか?
ご教示いただければ幸いです。よろしくお願いします。
 
 
 
また、XMLでの定義はしないようにしています。
全てJavaでスタイルを設定するようにしています。
Reply all
Reply to author
Forward
0 new messages