RecyclerView - notifyDataSetChanged() - Kotlin - 不工作 [英] RecyclerView - notifyDataSetChanged() - Kotlin - Not Working

查看:80
本文介绍了RecyclerView - notifyDataSetChanged() - Kotlin - 不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用单独的 URL 调用更新数据后,我在 RecyclerView 中重新加载数据时遇到问题.FristFragment 调用 LoadDataFromUrl 并在 Recycler View 中显示数据.每个 Recycler 的视图项都有一个带有 OnSetClickListener 的按钮,该按钮调用另一个 URL 来更新项的名称数据.在用户更新项目名称并收到成功响应后,原始 myResponse 数据将更新为新项目的名称.当数据更新时,我需要在 Recycer View` 中重新加载数据,但我无法弄清楚.我花了两天时间试图修复它,但我无法让它运行.任何帮助将不胜感激!

I am having an issue with reloading data in RecyclerView after the data is updated with a separate URL call. The FristFragment calls LoadDataFromUrl and displays the data in the Recycler View. Each Recycler's view item has a button with OnSetClickListener that calls another URL to update item's name data. After the user updates the item's name and a successful response is received, then the original myResponse data is updated with the new item's name. When the data is updated, I need to reload data in the Recycer View` but I can not figure it out. I spent two days trying to fix it but I can't get it running. Any help would be greatly appreciated!

数据模型:

DataModel.kt
class MyResponse (var Status: String = "", val items: List<Items> = emptyList())
class Items(var ItemId: String = "", var ItemName: String = "")

回收者视图代码:

Adapter.kt
var recyclerView: RecyclerView? = null

class MainAdapter(val myResponse: MyResponse): RecyclerView.Adapter<CustomViewHolder>(){

    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {

        val layoutInflater = LayoutInflater.from(parent?.context)

        val cellForRow = layoutInflater.inflate(R.layout.my_custom_cell, parent,false)

        return CustomViewHolder(cellForRow)

    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {



        val item = myResponse.items.get(position)


        //there is a button for each item in the list that will call a function ButtonPressed from Frist Fragment
        holder.view.button.setOnClickListener {
        
                val firstFragment = FirstFragment()
                firstFragment.ButtonPressed(item.ItemId,item.ItemName, position)

        }
        
         holder.view.textView_ItemID = item.itemId
         holder.view.textView_Item_Name = item.itemName
    }


        class CustomViewHolder(val view: View, var Items: Item? = null): RecyclerView.ViewHolder(view){

    }
}

然后我有一个片段 Fragment.kt

Then I have a fragment Fragment.kt

FirstFragment.kt    
class FirstFragment : Fragment() {
    

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

 override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?

    ): View? {
        val rootView =  inflater.inflate(R.layout.first_fragment, container, false)
        return rootView
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        LoadDataFromUrl()
        recyclerView.layoutManager = LinearLayoutManager(this.context,
            LinearLayoutManager.HORIZONTAL, false)
       
    }   

    //this function loads data on create view 
    fun LoadDataFromUrl(){

        
        val url = "some_url"
        val payload = "some_data_to_send"
        val requestBody = payload.toRequestBody()
        val request = Request.Builder()

            .method("POST",requestBody)
            .url(url)
            .build()

        val client =  OkHttpClient()

        client.newCall(request).enqueue(object : Callback {

            override fun onFailure(call: Call, e: IOException) {

                println("error")

            }

            override fun onResponse(call: Call, response: Response) {

                val body = response?.body?.string()

                val gson = GsonBuilder().create()

                myResponse = gson.fromJson(body, MyResponse::class.java)

                activity?.runOnUiThread {

                    if (myResponse.Status== "200"){
                    
                        recyclerView.adapter = MainAdapter(myResponse)
                        
                    } 
                }
            }
        })
    }

    fun ButtonPressed(itemId: String, itemName: String, position: Int){

        val url = "some_another_url"
        val payload = "some_another_data_to_send"
        val requestBody = payload.toRequestBody()

        val request = Request.Builder()

                .method("POST",requestBody)
                .url(url)
                .build()

        val client =  OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                println("error")
            }
            
            override fun onResponse(call: Call, response: Response) {
                val body = response?.body?.string()
                val gson = GsonBuilder().create()
                val buttomPressedResponse = gson.fromJson(body, ButtonPressedResponse::class.java)

                    if (buttonPressedResponse.Status== "200") {

                        myResponse.response[position].Status = buttomPressedResponse.Status //will update existing object myResponse with a new item's name
                        
                       //this is where I have a problem
                        recyclerView.adapter.notifyDataSetChanged()

                    } 
           
        }
    }
}

我尝试了以下更改,但仍然出现错误.

I tried the following changes but I still get an error.

//I get this error: Fatal Exception: OkHttp Dispatcher Process. recyclerView must not be null. Then the app crashes and the view reloads. If I clcik the Button again I get an error saying: RecyclerView: No adapter atatched. Skipping layout. 
activity?.runOnUiThread {
myResponse.response[position].Status = checkInOutResponse.Status //will update existing object myResponse with updated data
recyclerView.adapter?.notifyDataSetChanged()
}

我也尝试在它上面运行 runOnUiTHread 但这段代码没有任何反应

I also tried to run on it runOnUiTHread but nothing happens with this code

activity?.runOnUiThread {
    myResponse.response[position].Status = checkInOutResponse.Status //will update existing object myResponse with updated data
recyclerView.adapter?.notifyDataSetChanged()
}   

推荐答案

在 Adapter 中创建 var myResponse: MyResponse 变量

Create var myResponse: MyResponse variable in Adapter

Adapter.kt
var recyclerView: RecyclerView? = null

class MainAdapter(val myResponseInit: MyResponse): RecyclerView.Adapter<CustomViewHolder>(){
    var myResponse: MyResponse
    
    myResponse = myResponseInit

    fun submitMyResponse(data: MyResponse) {
        myResponse = data
    }

    //Rest of the code onCreateViewHolder etc.
}

每次收到响应时,在适配器上调用 submitMyResponse() 函数和 notifyDataSetChanged().

Call submitMyResponse() function and notifyDataSetChanged() on adapter everytime you receive response.

这篇关于RecyclerView - notifyDataSetChanged() - Kotlin - 不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆