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

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

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

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

Android Studio

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

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

4946閲覧

recyclerviewに格納されているラジオボタンのチェックをfalseにしたい

kbayashi

総合スコア18

Android

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

Android Studio

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

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2020/04/24 14:28

今現在firebaseとandroid studioで出会い系アプリを作っています。

自分のプロフィール画面で各項目をタップするとダイアログを表示し、ダイアログに表示されている項目を選択し保存を押すとデータベスに保存されるようになっていますが少し問題があります。

まず、ダイアログの説明として、ダイアログにrecyclerviewを使用しデータベースに保存されている、選択項目を表示させており、添付画像のダイアログではrecyclerviewに表示するデータにラジオボタンを使用しています。
イメージ説明

##問題
ラジオボタンが押された場合、 押されたラジオボタン以外のチェックプロパティをfalseにするという処理を書いていますが問題がありまして、画面に映されていないrecyclerviewのデータを参照しようとしたときにjava.lang.IndexOutOfBoundsExceptionが発生します。Dialog.ktのadapterSet関数内のdialog?.one_select_dialog_recyclerview?.get(i) が原因だとわかるのですが、調べては見ましたが、これ以外の方法でrecyclerviewに格納されているラジオボタンを参照すればいいかわかりません。 recyclerviewにはGroupie(2.1.0)を使ってデータを追加しています。

##コード

Dialog.kt

kotlin

1 2class OneSelectDialog(val value:String): DialogFragment() { 3 4 val adapter = GroupAdapter<ViewHolder>() 5 6 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { 7 8 //ダイアログのインスタンス取得 9 val dialog: Dialog = Dialog(activity!!) 10 //タイトルバーなしのダイアログを表示 11 dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) 12 //フルスクリーンでダイアログを表示 13 dialog.window?.setFlags( 14 WindowManager.LayoutParams.FLAG_FULLSCREEN, 15 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) 16 //レイアウト指定 17 dialog.setContentView(R.layout.oneselect_set_dialog) 18 19 //背景色を透明に 20 dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) 21 dialog.window?.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT) 22 23 24 dialog.one_select_dialog_recyclerview.adapter = adapter 25 26 adapterSet() 27 28 29 //キャンセル 30 dialog.one_selecy_dialog_cancel_button.setOnClickListener { 31 dialog.cancel() 32 } 33 //保存 34 dialog.one_selecy_dialog_save_button.setOnClickListener { 35 36 DatabaseSave() 37 dialog.cancel() 38 } 39 40 return dialog 41 } 42  //データベースの保存 43 private fun DatabaseSave(){ 44 45 val uid = FirebaseAuth.getInstance().uid 46 47 var i = 0 48 //チェックされたボタンを探してその項目を保存する 49 while(i < adapter.itemCount) { 50 51 var item = dialog?.one_select_dialog_recyclerview?.get(i) 52 53 if(item!!.oneselect_recyclerview_radiobutton!!.isChecked){ 54 var ref = FirebaseDatabase.getInstance() 55 .getReference("users/$uid/$value") 56 ref.setValue(item.oneselect_recyclerview_radiobutton.text.toString()) 57 } 58 59 i++ 60 } 61 62 } 63 64 65 private fun adapterSet(){ 66 67 val ref = FirebaseDatabase.getInstance().getReference("/$value") 68 69 //チェックされたボタン以外のラジオボタンのチェックを外す 70 val listener:((Int)-> Unit) = { potion -> 71 var i = 0 72 Log.d(DIALOG, "$potion") 73 while (i < adapter.itemCount) { 74 var item = dialog?.one_select_dialog_recyclerview?.get(i) 75 if(i != potion) { 76 item?.oneselect_recyclerview_radiobutton?.isChecked = false 77 } 78 i++ 79 } 80 } 81 82 ref.addListenerForSingleValueEvent(object: ValueEventListener{ 83 override fun onCancelled(p0: DatabaseError) { 84 85 } 86 87 override fun onDataChange(p0: DataSnapshot) { 88 p0.children.forEach { 89 Log.d(DIALOG, it.value.toString()) 90 adapter.add(OneSelectDialogItem(it.value.toString(), listener)) 91 } 92 93 } 94 95 }) 96 } 97 98 99 100} 101 102class OneSelectDialogItem(val text: String, val listener: ((Int)-> Unit)): Item<ViewHolder>(){ 103 104 override fun bind(viewHolder: ViewHolder, position: Int) { 105 viewHolder.itemView.oneselect_recyclerview_radiobutton.text = text 106 107 viewHolder.itemView.oneselect_recyclerview_radiobutton.setOnClickListener { 108 Log.d(DIALOG, viewHolder.itemView.oneselect_recyclerview_radiobutton.text.toString()) 109 Log.d(DIALOG, "${viewHolder.itemView.oneselect_recyclerview_radiobutton.isChecked}") 110 Log.d(DIALOG, "$position") 111 listener.invoke(position) 112 } 113 } 114 115 116 override fun getLayout(): Int { 117 return R.layout.oneselect_recyclerview_row 118 } 119}

oneselect_set_dialog

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/linearLayout13" 6 android:layout_width="match_parent" 7 android:layout_height="wrap_content" 8 android:layout_margin="8dp" 9 android:background="@drawable/dialog_rounted" 10 android:orientation="vertical"> 11 12 <TextView 13 android:id="@+id/one_select_dialog_textview" 14 android:layout_width="0dp" 15 android:layout_height="wrap_content" 16 android:background="@drawable/dialog_title" 17 android:text="スタイル" 18 android:textAlignment="center" 19 android:textColor="@android:color/black" 20 android:textSize="30sp" 21 android:textStyle="bold" 22 app:layout_constraintEnd_toEndOf="parent" 23 app:layout_constraintStart_toStartOf="parent" 24 app:layout_constraintTop_toTopOf="parent" /> 25 26 <androidx.recyclerview.widget.RecyclerView 27 android:id="@+id/one_select_dialog_recyclerview" 28 android:layout_width="0dp" 29 android:layout_height="200dp" 30 android:layout_marginStart="8dp" 31 android:layout_marginTop="8dp" 32 android:layout_marginEnd="8dp" 33 android:background="@drawable/dialog_edittext_dezain" 34 android:padding="5dp" 35 app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" 36 app:layout_constraintEnd_toEndOf="parent" 37 app:layout_constraintStart_toStartOf="parent" 38 app:layout_constraintTop_toBottomOf="@+id/one_select_dialog_textview"> 39 40 </androidx.recyclerview.widget.RecyclerView> 41 42 <LinearLayout 43 android:layout_width="0dp" 44 android:layout_height="wrap_content" 45 android:layout_marginTop="8dp" 46 app:layout_constraintEnd_toEndOf="parent" 47 app:layout_constraintStart_toStartOf="parent" 48 app:layout_constraintTop_toBottomOf="@+id/one_select_dialog_recyclerview"> 49 50 <Button 51 android:id="@+id/one_selecy_dialog_cancel_button" 52 android:layout_width="wrap_content" 53 android:layout_height="wrap_content" 54 android:layout_weight="1" 55 android:background="@drawable/dialog_button_cancel" 56 android:text="キャンセル" 57 android:textAlignment="center" 58 android:textColor="@android:color/white" 59 android:textSize="18sp" 60 android:textStyle="bold" /> 61 62 <Button 63 android:id="@+id/one_selecy_dialog_save_button" 64 android:layout_width="wrap_content" 65 android:layout_height="wrap_content" 66 android:layout_weight="1" 67 android:background="@drawable/dialog_button_ok" 68 android:text="保存" 69 android:textAlignment="center" 70 android:textColor="@android:color/white" 71 android:textSize="18sp" 72 android:textStyle="bold" /> 73 74 </LinearLayout> 75 76 77</androidx.constraintlayout.widget.ConstraintLayout>

oneselect_recyclerview_row

xml

1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_marginBottom="5dp" 5 android:layout_height="wrap_content" 6 android:orientation="vertical"> 7 8 <RadioButton 9 android:id="@+id/oneselect_recyclerview_radiobutton" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:text="RadioButton" 13 android:textColor="@android:color/black" 14 android:textSize="16sp" 15 android:textStyle="bold" /> 16</LinearLayout>

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

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

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

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

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

guest

回答2

0

本来 Adapter が行う処理が漏れた形になってしまうようなので, ("Groupie" が分かりませんので)
素直に Adapter を実装してみます.
DB(firebase)部分はハードコーディングとログ表示としています.

kotlin

1class StyleDialog() : DialogFragment() { 2 3 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { 4 //ダイアログのインスタンス取得 5 val dialog: Dialog = Dialog(context!!) 6 //タイトルバーなしのダイアログを表示 7 dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) 8 //レイアウト指定 9 dialog.setContentView(R.layout.one_select_set_dialog) 10 dialog.window?.apply { 11 //フルスクリーンでダイアログを表示 12 setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) 13 14 //背景色を透明に 15 setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) 16 setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT) 17 } 18 19 var adapter = StyleViewAdapter(context!!) 20 loadStyles(adapter) 21 dialog.one_select_dialog_recyclerview.adapter = adapter 22 23 //キャンセル 24 dialog.one_selecy_dialog_cancel_button.setOnClickListener { 25 dialog.cancel() 26 } 27 //保存 28 dialog.one_selecy_dialog_save_button.setOnClickListener { 29 saveDatabase(adapter) 30 dialog.cancel() 31 } 32 33 return dialog 34 } 35 36 private fun loadStyles(adapter: StyleViewAdapter) { 37 adapter.add("~149") 38 adapter.add("150~154") 39 adapter.add("155~159") 40 adapter.add("160~164") 41 adapter.add("165~169") 42 adapter.add("170~174") 43 adapter.add("175~179") 44 adapter.add("180~") 45 } 46 47 //データベースの保存 48 private fun saveDatabase(adapter: StyleViewAdapter) { 49 Log.d("StyleDialog", "**** StyleViewAdapter.checkedText='${adapter.checkedText}' ****") 50 } 51} 52 53class StyleViewAdapter(private val context: Context) : RecyclerView.Adapter<StyleViewAdapter.ViewHolder>() { 54 class StyleItem(val text: String) {} 55 class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 56 val radioButton: RadioButton = itemView.findViewById(R.id.oneselect_recyclerview_radiobutton) 57 } 58 59 private var itemList = mutableListOf<StyleItem>() 60 private var checkedPosition: Int = 0 61 public val checkedText: String 62 get() = itemList[checkedPosition].text 63 64 fun add(style: String) { 65 itemList.add(StyleItem(style)) 66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StyleViewAdapter.ViewHolder { 69 val layoutInflater = LayoutInflater.from(context) 70 val layout = layoutInflater.inflate(R.layout.one_select_recyclerview_row, parent, false) 71 return StyleViewAdapter.ViewHolder(layout) 72 } 73 74 override fun getItemCount(): Int = itemList.size 75 76 override fun onBindViewHolder(holder: StyleViewAdapter.ViewHolder, position: Int) { 77 holder.radioButton.text = itemList[position].text 78 holder.radioButton.setOnClickListener(null) //一度外さないと, 再利用時に check の更新で前のが動く(ラジオボタンなら害無し?) 79 holder.radioButton.isChecked = (position == checkedPosition) 80 holder.radioButton.setOnClickListener { 81 val oldPosition = checkedPosition 82 if (oldPosition != position) { 83 checkedPosition = position 84 notifyItemChanged(oldPosition) 85 } 86 } 87 } 88}

投稿2020/04/25 13:11

jimbe

総合スコア13209

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

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

kbayashi

2020/04/26 09:00

回答ありがとうございます。 もし、groupieを使わず実装する場合は、こちらを参考にさせていただきます。
guest

0

ベストアンサー

チェックするかどうかはbindでしてやるようにして、データを別で持っておいてnotifyDataSetChangedを呼び出すような感じで実装すると良いかと思います。(他に良い書き方があるかもしれません、あくまで一例として)
Firebaseからではなく、ローカルで作成したデータでサンプル実装しました。

class OneSelectDialog(val value:String): DialogFragment() { val adapter = GroupAdapter<ViewHolder>() private var listItem = mutableListOf<OneSelectDialogItem>() override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { //ダイアログのインスタンス取得 val dialog: Dialog = Dialog(activity!!) //タイトルバーなしのダイアログを表示 dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) //フルスクリーンでダイアログを表示 dialog.window?.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN) //レイアウト指定 dialog.setContentView(R.layout.oneselect_set_dialog) //背景色を透明に dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) dialog.window?.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT) dialog.one_select_dialog_recyclerview.adapter = adapter adapterSet() //キャンセル dialog.one_selecy_dialog_cancel_button.setOnClickListener { dialog.cancel() } //保存 dialog.one_selecy_dialog_save_button.setOnClickListener { dialog.cancel() } return dialog } private fun adapterSet(){ //チェックされたボタン以外のラジオボタンのチェックを外す val listener:((Int)-> Unit) = { potion -> // 全部falseにする listItem.forEach { it.checked = false } listItem[potion].checked = true // データ変更があったことを伝える adapter.notifyDataSetChanged() } listItem.add(OneSelectDialogItem("1", true, listener)) listItem.add(OneSelectDialogItem("2", false, listener)) listItem.add(OneSelectDialogItem("3", false, listener)) listItem.add(OneSelectDialogItem("4", false, listener)) listItem.add(OneSelectDialogItem("5", false, listener)) listItem.add(OneSelectDialogItem("6", false, listener)) listItem.add(OneSelectDialogItem("7", false, listener)) listItem.add(OneSelectDialogItem("8", false, listener)) listItem.add(OneSelectDialogItem("9", false, listener)) listItem.forEach { adapter.add(it) } } } class OneSelectDialogItem(val text: String, var checked:Boolean, val listener: ((Int)-> Unit)): Item<ViewHolder>(){ override fun bind(viewHolder: ViewHolder, position: Int) { viewHolder.itemView.oneselect_recyclerview_radiobutton.text = text viewHolder.itemView.oneselect_recyclerview_radiobutton.isChecked = checked viewHolder.itemView.oneselect_recyclerview_radiobutton.setOnClickListener { listener.invoke(position) } } override fun getLayout(): Int { return R.layout.oneselect_recyclerview_row } }

投稿2020/04/25 06:59

razuma

総合スコア1313

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

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

kbayashi

2020/04/25 08:12

回答ありがとうございます。 例外が発生することなく正常に動作しました!ありがとうございました。
razuma

2020/04/25 08:18

良かったです。アプリ作成がんばってくださいー。
kbayashi

2020/04/25 08:21

励みになります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問