#チェックの状態が変わってしまう
まず、スクロールするほどのチェックを追加したとして、それでスクロールしたらなぜかチェックの状態が変わってしまうのです。
↑のように、アイテム1がチェックされていない状態でスタートして、
↑のように、アイテム1にチェックを入れます。
↑のように、下にスクロールします。
すると、なんと↑のように、チェックの状態が変わってしまうのです。(アイテム1が。)
#変わってしまう理由
まず、画面外になってしまった場合はその項目は廃棄されます。(再利用される)
独自adapterのコードではgetView(...)というところがありますよね。
それは各行が読み込まれたときに呼ばれる関数なんです。
廃棄されるので、そのgetViewのところでもっかい反映させないといけないんです。
#チェックリストのコードは大きく分けて二つの種類
・SimpleAdapter
・ArrayAdapter
(listViewDataは独自のclassの名前)
##SimpleAdapter
これは主にMapを使う方法です。Mapに"check"と"name"を作成して、それをputする感じです。
しかし、この方法だとダメでした。
だめというか、自分の知能だと解決できませんでした。getItem(position)などから
チェックの状態を反映させてもだめでした。
##ArrayAdapter
この方法を使って解決しました。
これは独自のclassからsetTextDataとかをしたりsetCheckedをしたりgetTextDataからgetViewのところでセットしたり、
getCheckedからgetViewのところでセットしたりとする感じです。
なかなかこの説明では理解しずらいと思いますが、まぁこの方法を使えば解決できるということです。
#どこをどのように変更したのか
まず、SimpleAdapterを使うのは無理だと分かったので、ArrayAdapterを継承したやつにしまた。
そして独自AdapterのgetViewのところをこうしました。
public View getView(int position, View convertView, ViewGroup parent) {
// 特定行(position)のデータを得る
MyData item = (MyData)getItem(position);
// convertViewは使いまわされている可能性があるのでnullの時だけ新しく作る
if (null == convertView) convertView = mLayoutInflater.inflate(R.layout.list, null);
// MyDataのデータをViewの各Widgetにセットする
TextView textView = convertView.findViewById(R.id.textView);
textView.setText(item.getTextData());
CheckBox checkBox = convertView.findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(item.isChecked());
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
MyData MyData = getItem(position);
MyData.setChecked(b);
}
});
return convertView;
}
まず最初に注目してほしいのがここです。
// MyDataのデータをViewの各Widgetにセットする
TextView textView = convertView.findViewById(R.id.textView);
textView.setText(item.getTextData());
CheckBox checkBox = convertView.findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(item.isChecked());
この行がないと、なにもないチェックの状態もfalseでtextViewのデータも空の状態になってしまいます。
checkBoxは念のため、リスナーを外してから、反映しています。
そしてからcheckBoxにチェンジリスナ―を付けました。
また、
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
MyData MyData = getItem(position);
MyData.setChecked(b);
}
});
というふうに、チェンジリスナーをつけておかないと、ずっとチェックがfalseになってしまうため、スクロールして画面外になると勝手にチェックが外されるといった挙動になります。
実際に作ってみました↓
Android Studio の ListView に CheckBox を追加する | チェックリストを作成