前提・実現したいこと
チーム管理系のアプリを作成しています。
アプリを起動すると、Firebaseへ自動ログインされ、その後Firebaseから、ユーザー固有のデータ(その人が所属しているチーム一覧データ)を取得し、RecyclerViewに反映させます。
発生している問題・エラーメッセージ
起動しても、RecyclerViewが空のままで、反映されません。
しかし、FABをクリックして、ダイアログを表示させ、そこのEditTextをタップして、キーボードが出てくると、後ろのほうでチーム一覧が出現し、その後ダイアログを閉じてもそのまま残っています。(アプリを再起動するとまた最初、空のまま表示される。)
該当のソースコード
TeamActivity
1class TeamActivity : AppCompatActivity() { 2 3 4 override fun onCreate(savedInstanceState: Bundle?) { 5 super.onCreate(savedInstanceState) 6 7 //端末内に保存されているメアドパスデータを取得 8 val data = getSharedPreferences("Data", Context.MODE_PRIVATE) 9 var Emaildata = data.getString("Email", null) 10 var Passdata = data.getString("Passwoed", null) 11 12 if ((Emaildata != null) && (Passdata != null)) { 13 val mAuth = FirebaseAuth.getInstance() 14 mAuth.signInWithEmailAndPassword(Emaildata, Passdata) 15 .addOnCompleteListener { 16 if (it.isSuccessful) { 17 Toast.makeText(applicationContext, "ログインしました", Toast.LENGTH_LONG).show() 18 // 成功処理 19 } else { 20 Toast.makeText( 21 applicationContext, 22 "ログインに失敗しました\n申し訳ありませんがもう一度\nもう一度登録しなおしてください", 23 Toast.LENGTH_LONG 24 ).show() 25 // 失敗処理 26 } 27 } 28 29 // [START check_current_user] 30 } 31 32 33 val user = Firebase.auth.currentUser 34 if (user != null) { 35 // User is signed in 36 } else { 37 // No user is signed in 38 val intent = Intent(applicationContext, LoginActivity::class.java) 39 //第2画面に送るデータを格納。 40 startActivity(intent) 41 } 42 // [END check_current_user] 43 setContentView(R.layout.activity_team) 44 45 val layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false) 46 47 // アダプターとレイアウトマネージャーをセット 48 val TeamRecyclerView = findViewById<RecyclerView>(R.id.TeamRecyclerView) 49 val adapter = CustomAdapter(TeamList()) 50 TeamRecyclerView.layoutManager = layoutManager 51 TeamRecyclerView.setHasFixedSize(true) 52 TeamRecyclerView.adapter = adapter 53 54 val makefab = findViewById<FloatingActionButton>(R.id.sub_btn1) 55 val joinfab = findViewById<FloatingActionButton>(R.id.sub_btn2) 56 makefab.setOnClickListener(MakeFabClickListener()) 57 joinfab.setOnClickListener(JoinFabClickListener()) 58 } 59 60 private inner class MakeFabClickListener : View.OnClickListener { 61 override fun onClick(v: View?) { 62 val dialogFragment = MakeTeamDialogFragment() 63 dialogFragment.show(supportFragmentManager, "MakeTeamDialogFragment") 64 } 65 } 66 67 private inner class JoinFabClickListener : View.OnClickListener { 68 override fun onClick(v: View?) { 69 val dialogFragment = JoinTeamDialogFragment() 70 dialogFragment.show(supportFragmentManager, "JoinTeamDialogFragment") 71 } 72 } 73} 74fun TeamList(): MutableList<MutableMap<String, String>> { 75 val uid = Firebase.auth.currentUser?.uid.toString() 76 val dbc = FirebaseFirestore.getInstance() 77 val teamList: MutableList<MutableMap<String, String>> = mutableListOf() 78 dbc.collection("Users").document(uid).get() 79 .addOnSuccessListener { 80 val dataList = it.data 81 var team = mutableMapOf<String,String>() 82 dataList?.forEach { 83 team = mutableMapOf("team" to it.value.toString()) 84 teamList.add(team) 85 } 86 } 87 return teamList 88} 89// ViewHolderクラスを作成 90class CustomViewHolder(val view: View) : RecyclerView.ViewHolder(view) { 91 val tvTeamname = view.tvteamname 92} 93 94class CustomAdapter(private val customList: MutableList<MutableMap<String,String>>) : RecyclerView.Adapter<CustomViewHolder>() { 95 96 // 上記のViewHolderクラスを使ってViewHolderを作成 97 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder { 98 val Inflater = LayoutInflater.from(parent.context) 99 val item = Inflater.inflate(R.layout.grid_view, parent, false) 100 return CustomViewHolder(item) 101 } 102 103 // ViewHolderに表示するデータを挿入 104 override fun onBindViewHolder(holder: CustomViewHolder, position: Int) { 105 val item = customList[position] 106 val teamname = item["team"] as String 107 holder.view.tvteamname.text = teamname 108 } 109 110 // getItemCount onCreateViewHolder onBindViewHolderを実装 111 // recyclerViewのコンテンツのサイズ 112 override fun getItemCount(): Int { 113 return customList.size 114 } 115}
activity_team.xml
grid_view.xml
JoinTeamDialogFragment
1class JoinTeamDialogFragment: DialogFragment() { 2 private val TAG = "JoinFragment" 3 4 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { 5 val activity = requireActivity() 6 val builder = AlertDialog.Builder(activity) 7 val inflater = activity.layoutInflater 8 val teamjoinview = inflater.inflate(R.layout.team_join_dialog,null) 9 10 11 builder.setView(teamjoinview) 12 .setTitle("チームを追加") 13 .setPositiveButton("参加"){dialog,id-> 14 //入力欄の有無を判別する// 15 val teamid =teamjoinview.findViewById<EditText>(R.id.etteamid) 16 val mynamej = teamjoinview.findViewById<EditText>(R.id.etmynamej) 17 val teamidEdi = teamid.text 18 val mynamejEdi = mynamej.text 19 20 //チームに参加(チームにuid追加)して、uidに所属チームを紐づける 21 if(!TextUtils.isEmpty(teamidEdi) && !TextUtils.isEmpty(mynamejEdi)){ 22 val uid = Firebase.auth.currentUser?.uid.toString() 23 val teamidStr = teamidEdi.toString() 24 val mynamejStr = mynamejEdi.toString() 25 val dbc = FirebaseFirestore.getInstance() 26 27 28 dbc.collection("Teams") 29 .document(teamidStr) 30 .collection("members") 31 .document("members") 32 .set(mapOf(uid to mynamejStr), SetOptions.merge()) 33 34 dbc.collection("Teams") 35 .document(teamidStr) 36 .get() 37 .addOnCompleteListener { task -> 38 if (task.isSuccessful) { 39 val document = task.result 40 if (document != null && document.data != null) { 41 val tname = document.data?.get("teamname") 42 dbc.collection("Users") 43 .document(uid) 44 .set(mapOf(teamidStr to tname), SetOptions.merge()) 45 }else { 46 } 47 }else { 48 } 49 } 50 .addOnFailureListener { e -> } 51 52 dbc.collection("Users").document(uid).get() 53 .addOnSuccessListener { 54 val dataList = it.data 55 val teamlist: MutableList<MutableMap<String, String>> = mutableListOf() 56 dataList?.forEach { 57 var team = mutableMapOf("team" to it.value.toString()) 58 teamlist.add(team) 59 } 60 61 val adapter = CustomAdapter(teamlist) 62 adapter.notifyDataSetChanged() 63 } 64 }else{ 65 Toast.makeText(activity,"チームコードとあなたのお名前を\n入力してください。",Toast.LENGTH_LONG).show() 66 } 67 //入力欄有無判別終了 68 } 69 .setNegativeButton("キャンセル"){dialog,id->} 70 return builder.create() 71 } 72 73 74}
画面がこうなります
↓
↓
↓ここでうしろにうっすらとチームのカードが出現している。
↓
試したこと
Firebaseからデータを持ってくる前に描画してしまっているのかなとは思いましたが、なんとも原因がわかりません。TeamActivityでadapterを設定した直後にnotifydatasetchangedを呼んでもみましたが、最初に描画はされないままでした。
ちなみにアダプタに渡すリストを固定の用意したリストにしたら、普通に最初から描画されました。ので、firebaseからとってきたデータをリストにして、アダプタに渡すところに問題があるのかなと思いました。
補足情報(FW/ツールのバージョンなど)
ちなみに、もうひとつのエラーとして、ダイアログにチームコードと名前を入力して、参加を押して、Firebaseのユーザーの所属チーム一覧に新しいチームのデータを追加して、notifydatasetchangedでRecyclerViewを更新しても、ダイアログが消えた後、RecyclerViewは更新されてないまま、前のチーム一覧が載っていたので、そちらもわかるかた、解決法ご教授いただきたいです。
何卒、皆様のお力をお貸しくださいmm