3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-06-22

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);のようにしてしまうと正常に動作しません。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?