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

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

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

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

Kotlin

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

Q&A

解決済

1回答

5614閲覧

Kotlin 最下部にスクロール後、RecyclerViewのリストを新しく追加する方法

Haruto513

総合スコア52

Android Studio

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

Kotlin

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

0グッド

1クリップ

投稿2020/01/21 06:46

編集2020/01/21 08:45

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

何か抜けているところがあるのか、わかる方がいたら教えてくださると助かります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

onScrollStateChangedメソッド内でRecyclerViewAdapterを作成しているので、
画面表示と連動しているRecyclerViewAdapterとは別のAdapterに対して、新しいitemを登録しています。

画面表示を更新したいなら、R.id.rvDrinkListのRecycleView(この場合、onScrollStateChangedの引数のrecyclerView)に設定されているRecyclerViewAdapterに対してaddItemしてください。

投稿2020/01/21 09:14

dsuzuki

総合スコア1682

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

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

Haruto513

2020/01/22 00:27

回答ありがとうございます。 回答を参考に private inner class scrollListener : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (!recyclerView.canScrollVertically(1)) { var datalist = mutableListOf<JSONObject>() for (index in 1..10) { datalist.add(_download!![index - 1]) } for (index in datalist.size..datalist.size + 10) { val adapter = recyclerView.adapter as RecyclerViewAdapter adapter.addItem(_download!![index]) } Toast.makeText(activity, "最終行です", Toast.LENGTH_LONG).show() } } } と書き直してみたところ、無事リサイクラービューの更新を行うことが出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問