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)
}
}
}
}
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.
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)
}
}
}
Überprüfen Sie diesen Code
if (resultCode == RESULT_OK) {
allList.clear()
allList=SettingHandler().getListAllSetting()
mCustomAdapter= CustomAdapter(allList)
mRecyclerView.adapter= mCustomAdapter
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
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
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)
}
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()
}
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()
yourAdapter (). notifyDataSetChanged