I customize a RecyclerView class which will display the content of val backupItemList: List<MSetting>
in Kotlin in Code B
Now I modify the data of backupItemList outside RecyclerView class, I think the Code D will display the latest data in UI, but I failed, the UI is still to display old data. I have to use Code C to display the latest data.
What's wrong with the 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)
}
}
}
}
To civic.LiLister:
Both Code C And Code D get the same result if I use Code E (I replace val with var),why?
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)
}
}
}
}
notifyItemChanged. Notify any registered observers that the item at position has changed with an optional payload object. This is an item change event, not a structural change event. It indicates that any reflection of the data at position is out of date and should be updated.
The secret maybe hide here:
class CustomAdapter (val backupItemList: List)
When you init an instance of CustomAdapter, the value is copied to property backupItemList, rather than assigned the reference. Therefore, when you change property allList of UIMain, the backupItemList won't change as you expected.
The solution is simple, as Ganesh Tikone wrote: add an method to update backupItemList.
fun updateData(data: List<MovieModel>) {
backupItemList.clear()
backupItemList.addAll(data)
notifyDataSetChanged()
}
and change Code D to:
//Code D
if (resultCode == RESULT_OK) {
allList=SettingHandler().getListAllSetting()
mCustomAdapter.updateData(allList)
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
Have a try.
In your Activity onCreate method
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)
}
}
}
In your code D, you are overwriting the reference for allList.
And the backupItemList in CustomAdapter has the reference for the same. So if you reassign the reference for allList the changes will not be picked up in recycler view
first make sure allList is mutable
val allList = mutableListOf<MSetting>()
then in code D
allList.clear()
allList.addAll(SettingHandler().getListAllSetting())
mCustomAdapter.notifyDataSetChanged()
Check this code,
if (resultCode == RESULT_OK) {
allList.clear()
allList=SettingHandler().getListAllSetting()
mCustomAdapter= CustomAdapter(allList)
mRecyclerView.adapter= mCustomAdapter
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With