Home > OS >  Recyclerview keep being reset
Recyclerview keep being reset

Time:02-18

I'm facing a problem with my recycler view, I'd wanted to refresh it every second, for that I use a timer which creates new request, but I think that my recyclerview is destroyed and directly recreated, when I'm scrolling it keep always returning to the top every second. Here is my fragment, I heard about layoutmanager but don't really know how to use it, is it linked?

class DlFragment (private val context: MainActivity): Fragment(){

private var myTimer: Timer? = null

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

    val view = inflater.inflate(R.layout.fragment_dl,container, false)

    val dlRecyclerView = view?.findViewById<RecyclerView>(R.id.dl_list_recycle_view)

    myTimer = Timer()

    myTimer!!.schedule(object : TimerTask() {
        override fun run() {
            getDlList(dlRecyclerView)
        }
    }, 0, 1000)
    
    val comfirmButton= view.findViewById<Button>(R.id.input_post_dl_button)
    comfirmButton.setOnClickListener { postDl(view) }                          

    return view
}

private fun getDlList(dlRecyclerView: RecyclerView?) {
    GlobalScope.launch(Dispatchers.Main) {
        try {
            val response = ApiClientQnap.apiServiceQnap.getQuery(0,20,"all","all",ApiClientQnap.sid)

            if (response.isSuccessful && response.body() != null) {
                val content = response.body()
                if (content != null) {
                    //println(content)
                    //val dlRecyclerView = view?.findViewById<RecyclerView>(R.id.dl_list_recycle_view)
                    dlRecyclerView?.adapter = DlAdapter(context,content.data)

                }
            } else { println("Error Occurred: ${response.message()}") }
        } catch (e: Exception) {println("Error Occurred: ${e.message}") }
    }
}

private fun postDl(view: View){

    val url_Dl = view.findViewById<EditText>(R.id.input_post_dl_text)

    GlobalScope.launch(Dispatchers.Main) {
        try {
            val response = ApiClientQnap.apiServiceQnap.postDL("Films","Films",
                url_Dl.text.toString(),ApiClientQnap.sid)

            if (response.isSuccessful && response.body() != null) {
                val content = response.body()
                println(response.body())
                if (content != null) {
                    if(content.error == 0) {
                        Toast.makeText(context, "yeee", Toast.LENGTH_LONG).show()
                        url_Dl.text.clear()
                    }
                    else
                        Toast.makeText(context, "no", Toast.LENGTH_LONG).show()
                }
            } else { println("Error Occurred: ${response.message()}") }
        } catch (e: Exception) {println("Error Occurred: ${e.message}") }
    }
}

Edit: Here's my DlAdapter

class DlAdapter(
    val context: MainActivity,
    private var dlList: ArrayList<Data>
    ) : RecyclerView.Adapter<DlAdapter.ViewHolder>() {


    class ViewHolder(view : View): RecyclerView.ViewHolder(view){
        val dl_title = view.findViewById<TextView>(R.id.dl_title)
        val dl_progress = view.findViewById<TextView>(R.id.dl_progress)
        val dl_speed = view.findViewById<TextView>(R.id.dl_speed)
        val progressBar = view.findViewById<ProgressBar>(R.id.progressBar)

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


        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.fragment_dl_list,parent,false)
        return ViewHolder(view)
    }

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

        val currentDl = dlList[position]

        holder.dl_title.text = currentDl.source_name

        holder.progressBar.progress = (currentDl.progress!!)

        when (currentDl.state) {
            5 -> holder.dl_progress.text = ("Terminé")
            2 -> holder.dl_progress.text = ("Arrété")
            4 -> holder.dl_progress.text = ("Echec")
            1 -> holder.dl_progress.text = (currentDl.progress.toString()   " % En pause")
            104 -> {
                holder.dl_progress.text = (currentDl.progress.toString()   " %")
                var toFloat = currentDl.down_rate?.toFloat()
                toFloat = toFloat?.div(1000000)   
                holder.dl_speed.text = (toFloat.toString() " Mo")

            }
        }
    }

    override fun getItemCount(): Int = dlList.size

    fun updateData(newData: ArrayList<Data>) {
        dlList.clear()
        dlList.addAll(newData)
        notifyDataSetChanged()
    }
}

CodePudding user response:

As @hardartcore suggested, you can try to convert the RecyclerView.Adapter to a ListAdapter and use a DiffUtil.ItemCallback class.

Try to convert your adapter like this:

class DlAdapter : ListAdapter<Data, DlAdapter.ViewHolder>(DlDiffCallback()) {

    class ViewHolder(view : View): RecyclerView.ViewHolder(view){
        val dl_title = view.findViewById<TextView>(R.id.dl_title)
        val dl_progress = view.findViewById<TextView>(R.id.dl_progress)
        val dl_speed = view.findViewById<TextView>(R.id.dl_speed)
        val progressBar = view.findViewById<ProgressBar>(R.id.progressBar)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.fragment_dl_list,parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // Use the getItem method to retrieve a specific item
        val currentDl = getItem(position)

        holder.dl_title.text = currentDl.source_name

        holder.progressBar.progress = (currentDl.progress!!)

        when (currentDl.state) {
            5 -> holder.dl_progress.text = ("Terminé")
            2 -> holder.dl_progress.text = ("Arrété")
            4 -> holder.dl_progress.text = ("Echec")
            1 -> holder.dl_progress.text = (currentDl.progress.toString()   " % En pause")
            104 -> {
                holder.dl_progress.text = (currentDl.progress.toString()   " %")
                var toFloat = currentDl.down_rate?.toFloat()
                toFloat = toFloat?.div(1000000)   
                holder.dl_speed.text = (toFloat.toString() " Mo")
            }
        }
    }
}

class DlDiffCallback : DiffUtil.ItemCallback<Data>() {
    // Change this method comparisons based on your equality conditions
    override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean = oldItem.id == newItem.id
    override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean = oldItem == newItem
}

You can then update your RecyclerView adapter by using the submitList method:

val adapter = DlAdapter()
adapter.submitList(content.data)
  • Related