質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

6763閲覧

ListViewでのCheckBoxにチェックが付かない

hiro094

総合スコア26

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2017/06/15 01:03

編集2017/06/16 05:18

###前提・実現したいこと
現在ListViewで一覧を表示しているのですが、項目のLongClickからチェックボックスが表示され、複数選択出来るようなものを作りたいと思っています。
実装は
ListVIew#setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
で長押しから複数選択モードに切り替え、実際に何件を選択済みというふうに実装できました。

###発生している問題・エラーメッセージ
しかし、ListView#setMultiChoiceModeListenerの
onItemCheckedStateChanged内にCheckBox#setCheckedメソッドを用いてチェックをしているのですが、実際のチェックボックスにチェックが付きません。
CheckBoxのインスタンス内のmChecked?は正しくFalseからTrueに変わっているのは確認出来たのですが、表示だけが変わらないようなのです。

CheckedTextViewも試しましたが同じ状態でした。

###該当のソースコード

xml

1 <CheckBox 2 android:id="@+id/chk_selected" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:clickable="false" 6 android:focusable="false" />

java

1 Fragment2 3 @Override 4 public void onActivityCreated(@Nullable Bundle savedInstanceState) { 5 super.onActivityCreated(savedInstanceState); 6 7 //...省略 8 lvContacts.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL); 9 lvContacts.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { 10 11 //...省略 12 @Override 13 public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { 14 CheckBox test = (CheckBox)lvContacts.getAdapter().getView(position, null, lvContacts).findViewById(R.id.chk_selected); 15 test.setChecked(checked); 16 int count = lvContacts.getCheckedItemCount(); 17 mode.setTitle(String.format("%d 件選択中", count)); 18 } 19 } 20 }

java

1Adapter2 @Override 3 public View getView(int position, View convertView, ViewGroup parent) { 4 convertView = layoutInflater.inflate(R.layout.list_item,parent,false); 5 6 ((TextView)convertView.findViewById(R.id.tv_title)).setText(memoList.get(position).getTitle()); 7 CheckBox cb = ((CheckBox)convertView.findViewById(R.id.chk_selected)); 8 9 return convertView; 10 } 11

###追記(2017/06/15 20:53)
ViewHolderを実装しても駄目だったのですが、チェックボックスの値を別に保持する必要があるとの記事を他に見たので、試しにそのような実装をAdapter#getViewのほうに追記した所チェックが反映されるようになりました。ただ、この記述方法がはたして正しいのか分からないので、これで正しいか、他に正しいor綺麗な記述方法があれば引き続きご回答よろしくお願いします。

java

1Adapter2 3 @Override 4 public View getView(final int position, View convertView, ViewGroup parent) { 5 final ReviewMemo item = (ReviewMemo) this.getItem(position); 6 ViewHolder holder; 7 8 if(convertView == null) { 9 convertView = layoutInflater.inflate(R.layout.list_item, parent, false); 10 holder = new ViewHolder(convertView); 11 convertView.setTag(holder); 12 checked.add(false); 13 }else{ 14 holder = (ViewHolder)convertView.getTag(); 15 } 16 holder.tvTitle.setText(item.getTitle()); 17 18 //checkedというListメンバを作り、保持するようにしました。 19 holder.chkSelected.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){ 20 @Override 21 public void onCheckedChanged(CompoundButton arg0, boolean arg1) { 22 checked.set(position, arg1); //チェックが変わるたびに 23 } 24 }); 25 holder.chkSelected.setChecked(checked.get(position)); 26 27 return convertView; 28 } 29 30 class ViewHolder{ 31 32 final TextView tvIndex; 33 final ImageView ivAvatar; 34 final TextView tvTitle; 35 final CheckBox chkSelected; 36 37 public ViewHolder(View itemView) { 38 tvIndex = (TextView) itemView.findViewById(R.id.tv_title); 39 ivAvatar = (ImageView) itemView.findViewById(R.id.iv_avatar); 40 tvTitle = (TextView) itemView.findViewById(R.id.tv_title); 41 chkSelected = (CheckBox)itemView.findViewById(R.id.chk_selected); 42 } 43 }

###追記2(2017/06/16 14:08)
リストの数が2つ以上の場合、ActionModeが切り替わってからのチェックが2つめからのチェックが付かない事が発覚しました。
何故かsetOnCheckedChangeListenerが2回目から呼ばれていないようです。
おそらくViewの部分だと思うのですが、かなり回りくどいことをしているように思います。

リストに画像を入れない場合、ListFragment#onActivityCreated内に以下だけを書くだけでチェックボックスまわりは全て動作出来ます。

java

1 setListAdapter(new ArrayAdapter<String>( 2 getActivity(), 3 android.R.layout.simple_list_item_checked, 4 mItems));

ここにImageViewを表示させたいだけなのですが、そうなるとArrayAdapterをカスタマイズしないといけない+なぜかチェックボックスまわりが機能しなくなってしまいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

内容は追記1で解決しましたが、
onItemCheckedStateChangedの中にアダプターのnotifyDataSetChangedメソッドで更新したら複数行あるものでも問題なく行けるようになりました。

java

1 Fragment2 3 @Override 4 public void onActivityCreated(@Nullable Bundle savedInstanceState) { 5 super.onActivityCreated(savedInstanceState); 6 7 //...省略 8 lvContacts.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL); 9 lvContacts.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { 10 11 //...省略 12 @Override 13 public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { 14 CheckBox test = (CheckBox)lvContacts.getAdapter().getView(position, null, lvContacts).findViewById(R.id.chk_selected); 15 test.setChecked(checked); 16 int count = lvContacts.getCheckedItemCount(); 17 mode.setTitle(String.format("%d 件選択中", count)); 18 19 //追加分 20 mAdapter.notifyDataSetChanged(); 21 } 22 } 23 }

投稿2017/06/16 10:40

hiro094

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

全てのソースコードが読めないため推測での回答になりますが、おそらくビューが使い回されているのではないでしょうか。

僕が昔書いたコードはこんな感じでした。

java

1@Override 2public View getView(final int position, View convertView, ViewGroup parent) 3{ 4 final MyClass item = this.getItem(position); 5 ViewHolder holder; 6 7 if (convertView == null) 8 { 9 convertView = myInflater.inflate(R.layout.some_layout, false); 10 holder = new ViewHolder(); 11 holder.one = (TextView) convertView.findViewById(R.id.one); 12 holder.two = (TextView) convertView.findViewById(R.id.two); 13 holder.three = (ImageView)convertView.findViewById(R.id.three); 14 convertView.setTag(holder); 15 } 16 else 17 { 18 holder = (ViewHolder) convertView.getTag(); 19 } 20 21 22 // 回答後に追記しました 23 holder.one.setText(item.getTextOne); 24 holder.two.setText(item.getTextTwo); 25 // 追記ここまで 26 27 return convertView; 28}

唐突に出てきた ViewHolder は単純な内部クラスです。

java

1private class ViewHolder 2{ 3 TextView one; 4 TextView two; 5 ImageView therr; 6}

具体的な回答ではありませんが、ご参考になれば。

投稿2017/06/15 05:33

編集2017/06/15 05:46
Yosuke-Kawakami

総合スコア123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro094

2017/06/15 12:01

回答ありがとうございます。 RecyclerViewではViewHolderを使っていたのですが、まだ知識が浅いためListViewにはいらないものだと思っていました。 しかし、このような実装をしてみなたのですが、やはりチェックは付きませんでした。 正しい解決かわからないのですが、チェックが付くようになりました。 問題はチェックボックスの値をそれぞれ保持する必要がある?事と、getViewの呼ばれるタイミングがよく分かっていないのですが、getViewでチェックボックスの値を再セットする必要がある?ようです。 よろしければ、引き続きなぜこれで上手く行ったのかと、他に正しい方法があればご回答のほどよろしくお願いします。
Yosuke-Kawakami

2017/06/16 14:53

問題が解決したようで何よりです。本件は満了していると思いますが getView の周りだけ補足しておきます。 --- getView() は各行が画面に表示されるタイミングで一行につき一回ずつ呼び出されます。ログの出力を確認した感じでは画面の大きさ + 数行程度のエリアを読み込んでいるようです。 各行の値は設定した Tag ID を基に正しく保持されています。 但し、画面の描画に構造上の難点があります。システムは有限なメモリ量を節約するために ListView で画面外にスクロールアウトした行を新しく表示する行に使いまわそうとします。この時、スクロールアウトした行の要素に値が入っていて、かつ新しく表示する行の要素に値が入っていない場合、(システムは初期値と判断して何も処理しないため)スクロールアウトした時点の外観のまま画面に表示されてしまいます。 これは行の見た目と実際に持っている値に差異が生じてしまうため、アプリケーション作成者の意図するところではありません。 この問題を解消するために holder.TextView.setText などを行います。試しにこの処理をコメントアウトしてみると、スクロールアウトした行の値が 2、3 行後くらいにスクロールインしてくる行の一部として表示される動作が確認できるはずです。 内容は以上です。 上記の内容は Android 3.x 時の古い認識であるため、もしかすると最新のバージョンでは異なっているかもしれません。その場合はごめんなさい。リスト処理は件数が大きくなってくると思わぬ不具合が出てくると思います。頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問