如何在Kotlin Volley请求代码中应用Callback回调填充RecyclerView数据
如何在Volley拉取数据的场景下使用Callback回调
原有场景与问题
核心逻辑为通过Volley拉取API接口数据,填充到列表中作为RecyclerView的数据源。原有代码存在异步请求问题:Volley网络请求为异步执行,原有代码直接返回列表时网络请求尚未完成,仅能返回本地硬编码的样例数据,接口返回的数据加载完成后无法通知上层更新UI。
原有核心代码
- 旧版createDataset实现
fun createDataset(): ArrayList<ItemPost>{ val url = "http://api.karawcraftventure.com/item" // 用于填充RecyclerView的列表变量 val list = ArrayList<ItemPost>() // Volley API请求 val Queue = Volley.newRequestQueue(activity) val jsonObject = JsonArrayRequest( Request.Method.GET,url,null, {response -> try { for (i in 0 until response.length()) { val item : JSONObject = response.getJSONObject(i) val API_Image : String = item.getString("product_url_image") val API_ItemName : String = item.getString("product_name") val API_Price : String = item.getString("product_price") val API_Category : String = item.getString("product_category") // 可以打开Toast测试数据是否正常提取 //Toast.makeText(context, "$API_ItemName - $API_Price - $API_Category", Toast.LENGTH_SHORT).show() list.add(ItemPost(API_Image, API_ItemName, API_Category, API_Price)) } } catch (e: JSONException) { e.printStackTrace() } }, { error: VolleyError? -> Toast.makeText(context, error?.message.toString(), Toast.LENGTH_SHORT).show() } ) // 本地硬编码的样例数据 list.add( ItemPost("https://karawcraftventure.com/uploads/ONGLO_KC1.jpg", "Item Title1", "Item Category1", "Item Price1" ) ) list.add( ItemPost("https://karawcraftventure.com/uploads/ORIOL_KC.jpg", "Item Title2", "Item Category2", "Item Price2" ) ) list.add( ItemPost("https://karawcraftventure.com/uploads/ORIOL_KC.jpg", "Item Title3", "Item Category3", "Item Price3" ) ) list.add( ItemPost("https://karawcraftventure.com/uploads/ORIOL_KC.jpg", "Item Title4", "Item Category4", "Item Price4" ) ) Queue.add(jsonObject) return list }
- 已创建的回调接口
interface ItemCallback { fun GetItem(Ar: ArrayList<ItemPost>) }
- 原有调用逻辑
private fun addDataSet() { val data = createDataset() ItemAdapter.SubmitList(data) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initRecyclerView() addDataSet() }
- 原有Adapter的SubmitList实现
fun SubmitList(ItemList : List<ItemPost>) { Items = ItemList }
最终解决方案
1. 修改createDataset函数
去除返回值,增加函数类型的回调参数,网络请求成功后将加载完成的数据通过回调抛出,无需保留本地硬编码样例数据。
fun createDataset(onSuccess: (List<ItemPost>) -> Unit){ val url = "http://api.karawcraftventure.com/item" // 用于填充RecyclerView的列表变量 val list = ArrayList<ItemPost>() // Volley API请求 val Queue = Volley.newRequestQueue(activity) val jsonObject = JsonArrayRequest( Request.Method.GET,url,null, {response -> try { for (i in 0 until response.length()) { val item : JSONObject = response.getJSONObject(i) val API_Image : String = item.getString("product_url_image") val API_ItemName : String = item.getString("product_name") val API_Price : String = item.getString("product_price") val API_Category : String = item.getString("product_category") // 可以打开Toast测试数据是否正常提取 //Toast.makeText(context, "$API_ItemName - $API_Price - $API_Category", Toast.LENGTH_SHORT).show() list.add(ItemPost(API_Image, API_ItemName, API_Category, API_Price)) } // 网络请求成功,将结果通过回调抛出 onSuccess(list) } catch (e: JSONException) { e.printStackTrace() } }, { error: VolleyError? -> Toast.makeText(context, error?.message.toString(), Toast.LENGTH_SHORT).show() } ) Queue.add(jsonObject) }
2. 修改Adapter的SubmitList方法
更新数据后调用notifyDataSetChanged触发RecyclerView刷新。
fun SubmitList(ItemList : List<ItemPost>) { Items = ItemList notifyDataSetChanged() }
3. 修改addDataSet方法
在createDataset的回调中接收加载完成的数据,传递给Adapter更新列表。
private fun addDataSet() { createDataset { list -> ItemAdapter.SubmitList(list) } }
内容的提问来源于stack exchange,提问作者Apprent1ce
相关产品推荐
相关产品推荐

