wake-up-neo.com

Wie binden Sie das Element in RecyclerView erneut, wenn sich die Daten in Kotlin geändert haben?

Ich passe eine RecyclerView-Klasse an, die den Inhalt von val backupItemList: List<MSetting> in Kotlin in Code B anzeigt

Jetzt ändere ich die Daten von backupItemList außerhalb der RecyclerView-Klasse. Ich denke, der Code D zeigt die neuesten Daten in der Benutzeroberfläche an, aber ich habe versagt, die Benutzeroberfläche ist immer noch die alten Daten anzeigen Daten.

Was ist los mit dem Code D?

Code A

class UIMain : AppCompatActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_main)                       

        allList= SettingHandler().getListAllSetting()            

        mRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
        mCustomAdapter= CustomAdapter(allList)
        mRecyclerView.adapter= mCustomAdapter


   }


   public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
       //Code C          
       if (resultCode == RESULT_OK) {
           allList=SettingHandler().getListAllSetting()
           mCustomAdapter= CustomAdapter(allList)
           mRecyclerView.adapter= mCustomAdapter
           mCustomAdapter.notifyDataSetChanged()
           mCustomAdapter.setSelectedItem(selectedBackupItem)  
       }


       //Code D     
       if (resultCode == RESULT_OK) {
          allList=SettingHandler().getListAllSetting()                
          mCustomAdapter.setSelectedItem(selectedBackupItem)                
       }         

   }        

}

Code B

  class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

        val noRecord=-1
        private var mSelectedItem = noRecord

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

        fun getSelectedItem():Int{
            return  mSelectedItem
        }

        fun setSelectedItem(index:Int){
            if (index in 0..(backupItemList.size-1) ){
                mSelectedItem=index
                notifyDataSetChanged();
            }

        }

        override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
            holder.bindItems(backupItemList[position])
        }

        override fun getItemCount(): Int {
            return backupItemList.size
        }

        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

            fun bindItems(aMSetting: MSetting) {
                itemView.tvSubject.text=aMSetting.name
                itemView.tvCreatedDate.text=aMSetting.createdDate.toDateString()
                itemView.tvDescription.text=aMSetting.description   
                itemView.radioButton.setOnClickListener {
                mSelectedItem=adapterPosition
                notifyDataSetChanged();
            }

            if(adapterPosition == 0 && mSelectedItem == noRecord) {             
                itemView.radioButton.isChecked = true
                mSelectedItem=adapterPosition
            }
            else {
                itemView.radioButton.isChecked =(adapterPosition == mSelectedItem)
            }       
            }

        }

    }

Zu civic.LiLister:

Sowohl Code C als auch Code D erhalten dasselbe Ergebnis, wenn ich Code E verwende (ich ersetze val durch var). Warum?

Code E

  class CustomAdapter (var backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

        val noRecord=-1
        private var mSelectedItem = noRecord

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

        fun getSelectedItem():Int{
            return  mSelectedItem
        }

        fun setSelectedItem(index:Int){
            if (index in 0..(backupItemList.size-1) ){
                mSelectedItem=index
                notifyDataSetChanged();
            }

        }

        override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
            holder.bindItems(backupItemList[position])
        }

        override fun getItemCount(): Int {
            return backupItemList.size
        }

        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

            fun bindItems(aMSetting: MSetting) {
                itemView.tvSubject.text=aMSetting.name
                itemView.tvCreatedDate.text=aMSetting.createdDate.toDateString()
                itemView.tvDescription.text=aMSetting.description   
                itemView.radioButton.setOnClickListener {
                mSelectedItem=adapterPosition
                notifyDataSetChanged();
            }

            if(adapterPosition == 0 && mSelectedItem == noRecord) {             
                itemView.radioButton.isChecked = true
                mSelectedItem=adapterPosition
            }
            else {
                itemView.radioButton.isChecked =(adapterPosition == mSelectedItem)
            }       
            }

        }

    }
6
HelloCW

Das Geheimnis kann sich hier verstecken:

klasse CustomAdapter (val backupItemList: List)

Wenn Sie eine Instanz von CustomAdapter initiieren, wird der Wert in die Eigenschaft backupItemList kopiert und nicht der Referenz zugewiesen. Wenn Sie die Eigenschaft allList von UIMain ändern, ändert sich die backupItemList daher nicht wie erwartet.

Die Lösung ist einfach, wie Ganesh Tikone schrieb: Fügen Sie eine Methode hinzu, um backupItemList zu aktualisieren.

fun updateData(data: List<MovieModel>) {
    backupItemList.clear()
    backupItemList.addAll(data)
    notifyDataSetChanged()
}

und ändern Sie Code D in:

//Code D     
   if (resultCode == RESULT_OK) {
      allList=SettingHandler().getListAllSetting()  
      mCustomAdapter.updateData(allList)    
      mCustomAdapter.setSelectedItem(selectedBackupItem)                
   }  

Probieren Sie es aus.

4
civic.LiLister

In Ihrer Activity onCreate-Methode

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.layout_main)                

                allList = ArrayList< MSetting>()
                mCustomAdapter = CustomAdapter(mChildList)
                mRecyclerView.layoutManager = LinearLayoutManager(context)
                mRecyclerView.adapter = mCustomAdapter
    }

> Now in onActivityResult



     public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {

           //Code C          
           if (resultCode == RESULT_OK) {
              if(data != null){
                 allList.clear()
                 allList.addAll(SettingHandler().getListAllSetting())
                 mCustomAdapter.notifyDataSetChanged()
                 mCustomAdapter.setSelectedItem(selectedBackupItem) 
              } 
           }

      }        
4
Shweta Chauhan

Überprüfen Sie diesen Code 

if (resultCode == RESULT_OK) {
           allList.clear()
           allList=SettingHandler().getListAllSetting()
           mCustomAdapter= CustomAdapter(allList)
           mRecyclerView.adapter= mCustomAdapter  
           mCustomAdapter.setSelectedItem(selectedBackupItem) 
       }
2
farhana

Das Problem ist, dass Sie keine binding verwenden. Das heißt, wenn Sie list ändern, wird Adapter dies nicht beachten. Daher werden nur alte Elemente angezeigt. Sobald Sie adapter über Änderungen in Ihrer Liste mit notifyDatasetChanged benachrichtigen, werden die Elemente aktualisiert mit neuen Daten. Wenn Sie mit code D eine Funktionalität erreichen möchten, müssen Sie die Datenbindung mithilfe des Beobachtbaren Musters verwenden. Weitere Informationen RecyclerView und Datenbindung

2
rajan ks

Fragment Code

private var adapter: RecentMovieAdapter? = null

Der Adapter wird in der onCreateView-Methode von fragment initialisiert

adapter = RecentMovieAdapter(activity, this)

Dies ist die Rückrufmethode in Fragment, bei der Daten vom Server mithilfe der Threading-Technik abgerufen werden

override fun onDataReceived(randomDialog: List<MovieModel>) {
    shimmerView!!.stopShimmerAnimation()
    shimmerView!!.visibility = View.GONE
    adapter!!.updateData(randomDialog)
}

Adapterklassencode

private var movieList: MutableList<MovieModel> = mutableListOf<MovieModel>()

Fügen Sie die Update-Funktion wie folgt in der Adapter-Klasse hinzu 

fun updateData(data: List<MovieModel>) {
    movieList.clear()
    movieList.addAll(data)
    notifyDataSetChanged()
}
2
Ganesh Tikone

In Ihrem Code D überschreiben Sie die Referenz für allList.

Und die backupItemList in CustomAdapter hat die Referenz für dasselbe ..__ Wenn Sie die Referenz für allList erneut zuweisen, werden die Änderungen nicht in der Recycler-Ansicht übernommen

stellen Sie zunächst sicher, dass allList veränderbar ist

val allList = mutableListOf<MSetting>()

dann im Code D

allList.clear()
allList.addAll(SettingHandler().getListAllSetting())
mCustomAdapter.notifyDataSetChanged()
2
AbdulAli

yourAdapter (). notifyDataSetChanged

0