Help us understand the problem. What is going on with this article?

[Android][Java] ListViewのCheckBoxの状態を管理する

More than 1 year has passed since last update.

2か月ほど詰まっていたので備忘録

実行環境

IDE:Android Studio 3.4
言語:Java

Xperia XZ3(実機デバッグに利用)
OSはAndroid 9 (API Level 28)

何がしたいか

ListView内のCheckBoxがスクロールによってそのチェック状態を変更されることがないようにする。

解決方法

ListViewで表示する要素を使いまわす処理をするgetViewメソッド内で、ListViewのCheckBoxのリスナーの貼り直しと、onCheckedChangedメソッド内でgetViewの引数のpositionを利用して改めてitemを取得する。

以下のコードには表記していませんが
ArrayAdapter< ListViewに表示するクラス型 >をextends(継承)、
ViewHolderパターンを使っています。

以下が成功例となります。

ListAdapter.java
// ListItemはListViewで表示する要素の自作クラス。
private ListItem item;
// 省略 ~~~~~~~~~~~~
public View getView (final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;

    if (convertView == null) {
        // convertViewに何もなければ新しく生成する。
        convertView = mInflater.inflate(mResId, parent, false);

        // リスト内の各アイテムの要素を取得。
        holder = new ViewHolder();
        holder.isActive = convertView.findViewById(R.id.alarm_active);

        convertView.setTag(holder);

    } else {
        holder = (ViewHolder)convertView.getTag();
    }

    // リストビューに表示するアイテムのインスタンスを取得する。
    item = getItem(position);

    // リスナーを剥がす。
    holder.isActive.setOnCheckedChangeListener(null);

    // 要素にpositionから取得したitem(自作クラスのインスタンス)を要素へ代入。
    holder.isActive.setChecked(item.isActive());

    // リスナーを貼る。
    holder.isActive.setOnCheckedChangeListener(
        new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged (CompoundButton cb, boolean isChecked) {
                ListItem listItem = getItem(position);
                // 対warning用nullチェック
                if (listItem != null){
                    listItem.setActive(isChecked);
                }
            }
        });

    return convertView;
}

ここで重要なのは匿名クラス内のonCheckedChangedメソッド内の
ListItem listItem = getItem(position);
という処理です。

この処理はチェック状態をリストの要素(自作クラス)に反映するためのものですが、
すでにitem = getItem(position);のようにされているからといってこの部分を削除し、
item.setActive(isChecked);のようにしてしまうと正常に動作しません。

Ur_ys_kn_k_
watashi wa kojin seisaksya desu
https://urysknk-blog.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away