KotlinでAndroidアプリ開発の勉強をしている最中です。
ダウンロードしたJSONデータをリサイクラービューに一部表示し、最下部までスクロールした時、残りのデータを表示するという動きを実現したいと考えています。
しかし、最下部までスクロールしたことを検知できたのはいいものの、RecyclerViewの内容を更新する書き方が、調べてもわかりませんでした。
以下のような流れでRecyclerViewを表示しています。
ボタンタップで、JSONをダウンロードしてからフラグメントを表示しています。
//質問の字数制限に達したので一部内容を消去しました。
②このようにしてRecyclerViewを表示しています。
Kotlin
1 2 private var _download : MutableList<JSONObject>? = null 3 private var _list : List<JSONObject>? = null 4 5 6 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 7 8 val extra = arguments 9 val downloadStr = extra?.getString("JsonData") 10 val array = JSONArray(downloadStr) 11 _download = array.toMutableList() 12 val firstView = _download!!.take(10) 13 _list = _download!!.drop(10) 14 15 val view = inflater.inflate(R.layout.listview_fragment, container, false) 16 17 val rvList = view.findViewById<RecyclerView>(R.id.rvDrinkList) 18 val layout = LinearLayoutManager(activity) 19 rvList.layoutManager = layout 20 21 val dataList = firstView 22 23 val adapter = RecyclerViewAdapter(dataList) 24 rvList.adapter = adapter 25 26 rvList.addOnScrollListener(scrollListener()) 27 val decorator = DividerItemDecoration(activity, layout.orientation) 28 rvList.addItemDecoration(decorator) 29 30 return view 31 } 32 33//略// 34 private inner class RecyclerViewAdapter(private val _listData: List<JSONObject>): RecyclerView.Adapter<RecyclerViewHolder>() { 35 override fun getItemCount(): Int { 36 LAST_POSITION = _listData.size 37 return _listData.size 38 } 39 override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) { 40 val list = _listData[position] 41 holder.tvname.text = list["name"].toString() 42 holder.tvkind.text = list["kind"].toString() 43 } 44 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder { 45 val holder = layoutInflater.inflate(R.layout.row, parent, false) 46 return RecyclerViewHolder(holder) 47 } 48 49 } 50//略//
③ここで、最下部までスクロールしたことを検知しています。
Kotlin
1 2private inner class scrollListener: RecyclerView.OnScrollListener() { 3 override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 4 super.onScrollStateChanged(recyclerView, newState) 5 6 if (!recyclerView.canScrollVertically(1)) { 7 8 Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() 9 10 } 11 } 12} 13 14
試したこと
読めないなりに英語のドキュメントやJavaでの情報を見てみて、以下のようにいくつか書いてみましたがRecyclerViewは更新されませんでした。
Kotlin
1 2 3private inner class scrollListener: RecyclerView.OnScrollListener() { 4 override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 5 super.onScrollStateChanged(recyclerView, newState) 6 7 if (!recyclerView.canScrollVertically(1)) { 8 9 Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() 10 11 RecyclerViewAdapter(list).notifyItemInserted(0) 12 13 } 14 } 15} 16 17
Kotlin
1 2private inner class scrollListener: RecyclerView.OnScrollListener() { 3 override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 4 super.onScrollStateChanged(recyclerView, newState) 5 6 if (!recyclerView.canScrollVertically(1)) { 7 8 Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() 9 10 RecyclerViewAdapter(list).notifyItemInserted(0) 11 recyclerView.adapter!!.notifyDataSetChanged() 12 13 } 14 } 15} 16 17
どのように書くのが正しいやり方なのでしょうか。
どなたか助言を頂けると助かります。
追記
こちらのページを参考に、記述を追加しましたがエラーが出ています。
http://bigbuddha.hatenablog.jp/entry/recyclerview-beginner
Kotlin
1 2 private inner class RecyclerViewAdapter( 3 private val _listData: MutableList<JSONObject>) 4 : RecyclerView.Adapter<RecyclerViewHolder>() 5 { 6 override fun getItemCount(): Int 7 { 8 LAST_POSITION = _listData.size 9 return _listData.size 10 } 11 fun addItem(item: JSONObject) { 12 _listData.add(item) 13 notifyDataSetChanged() 14 } 15 override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) 16 { 17 val list = _listData[position] 18 holder.tvname.text = list["name"].toString() 19 holder.tvkind.text = list["kind"].toString() 20 } 21 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder 22 { 23 val holder = layoutInflater.inflate(R.layout.row, parent, false) 24 return RecyclerViewHolder(holder) 25 } 26 27 } 28 29 private inner class scrollListener: RecyclerView.OnScrollListener() { 30 override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 31 super.onScrollStateChanged(recyclerView, newState) 32 33 if (!recyclerView.canScrollVertically(1)) { 34 35 val addlist = _list?.take(10) as MutableList<JSONObject> 36 val firstList = _list as MutableList<JSONObject> 37 _list = _list!!.drop(10) 38 39 Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() 40 41 for (index in 1..addlist.size) { 42 println(addlist[index - 1]) 43 RecyclerViewAdapter(firstList).addItem(addlist[index - 1]) 44 } 45. 46. 47. 48 49
リサイクラービューを設定するメンバクラスの中に、
kotlin
1 2fun addItem(item: JSONObject) { 3 _listData.add(item) 4 notifyDataSetChanged() 5 }
を追加しました。
そして上記の内容で実行すると、エラーが出てきました。
logcat
1 2java.lang.ClassCastException: kotlin.collections.EmptyList cannot be cast to kotlin.collections.MutableList 3 at jp.wings.nikkeibp.sampleapp.RecyclerViewFragment$scrollListener.onScrollStateChanged(RecyclerViewFragment.kt:100) 4
もう少し調べてみようと思います。
追記2
その後も少しずつ修正を加えていき、現在の記述は以下のようになっています。
Kotlin
1 2 3class RecyclerViewFragment : Fragment() { 4 5 private var _download: MutableList<JSONObject>? = null 6 7 8 override fun onCreateView( 9 inflater: LayoutInflater, 10 container: ViewGroup?, 11 savedInstanceState: Bundle? 12 ): View? { 13 14 val extra = arguments 15 val downloadStr = extra?.getString("JsonData") 16 val array = JSONArray(downloadStr) 17 _download = array.toMutableList() 18 19 var datalist = mutableListOf<JSONObject>() 20 for (index in 1..10) { 21 datalist.add(_download!![index - 1]) 22 } 23 24 val view = inflater.inflate(R.layout.listview_fragment, container, false) 25 26 val rvList = view.findViewById<RecyclerView>(R.id.rvDrinkList) 27 val layout = LinearLayoutManager(activity) 28 rvList.layoutManager = layout 29 30 val adapter = RecyclerViewAdapter(datalist) 31 rvList.adapter = adapter 32 33 rvList.addOnScrollListener(scrollListener()) 34 val decorator = DividerItemDecoration(activity, layout.orientation) 35 rvList.addItemDecoration(decorator) 36 37 return view 38 } 39 40 private inner class RecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 41 var tvname: TextView 42 var tvkind: TextView 43 44 init { 45 tvname = itemView.findViewById(R.id.name) 46 tvkind = itemView.findViewById(R.id.kind) 47 } 48 } 49 50 private inner class RecyclerViewAdapter( 51 private val _listData: MutableList<JSONObject> 52 ) : RecyclerView.Adapter<RecyclerViewHolder>() { 53 override fun getItemCount(): Int { 54 return _listData.size 55 } 56 57 fun addItem(item: JSONObject) { 58 _listData.add(item) 59 notifyDataSetChanged() 60 } 61 62 override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) { 63 val list = _listData[position] 64 holder.tvname.text = list["name"].toString() 65 holder.tvkind.text = list["kind"].toString() 66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder { 69 val holder = layoutInflater.inflate(R.layout.row, parent, false) 70 return RecyclerViewHolder(holder) 71 } 72 73 } 74 75 fun JSONArray.toMutableList(): MutableList<JSONObject> = 76 MutableList(length(), this::getJSONObject) 77 78 private inner class scrollListener : RecyclerView.OnScrollListener() { 79 override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 80 super.onScrollStateChanged(recyclerView, newState) 81 82 if (!recyclerView.canScrollVertically(1)) { 83 var datalist = mutableListOf<JSONObject>() 84 for (index in 1..10) { 85 datalist.add(_download!![index - 1]) 86 } 87 for (index in datalist.size..datalist.size + 10) { 88 val recyclerView = RecyclerViewAdapter(datalist) 89 recyclerView.addItem(_download!![index]) 90 } 91 Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() 92 } 93 } 94 } 95} 96
クラッシュするようなエラーはありませんが、最下部までスクロールし、scrollListenerが動くと、以下のようなログが出てくるのみで、リサイクラービューに変化は起こりませんでした。
logcat
1 22020-01-21 17:07:50.352 7484-7511/jp.wings.nikkeibp.sampleapp E/EGL_emulation: tid 7511: eglSurfaceAttrib(1354): error 0x3009 (EGL_BAD_MATCH) 32020-01-21 17:07:50.352 7484-7511/jp.wings.nikkeibp.sampleapp W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe2c46ac0, error=EGL_BAD_MATCH 4 5
何か抜けているところがあるのか、わかる方がいたら教えてくださると助かります。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/22 00:27