Reputation: 2255
The Code B is a customized RecyclerView apater with radio button.
mCustomAdapter is changed in both fun methodA() and fun methodB() in Code A, so the reference of get () = mCustomAdapter.getSelectedIndex()
is changed too, and it means that the val property mySelectedIndex get value from different address.
In my mind, the val property can't be changed, why doesn't the app cause error?
Code A
private lateinit var mCustomAdapter: CustomAdapter
private val mySelectedIndex get () = mCustomAdapter.getSelectedIndex()
private fun methodA(){
mCustomAdapter= CustomAdapter(allListA)
mRecyclerView.adapter= mCustomAdapter
backup(mySelectedIndex)
}
private fun methodB(){
mCustomAdapter= CustomAdapter(allListB)
mRecyclerView.adapter= mCustomAdapter
restore(mySelectedIndex)
}
Code B
class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
val noRecord=-1
private var mSelectedIndex = 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 getSelectedIndex():Int{
return mSelectedIndex
}
fun setSelectedIndex(index:Int){
if (index in 0..(backupItemList.size-1) ){
mSelectedIndex=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.radioButton.setOnClickListener {
mSelectedIndex=adapterPosition
notifyDataSetChanged();
}
if(adapterPosition == 0 && mSelectedIndex == noRecord) {
itemView.radioButton.isChecked = true
mSelectedIndex=adapterPosition
}
else {
itemView.radioButton.isChecked =(adapterPosition == mSelectedIndex)
}
}
}
}
Modified
I think the Code DD and Code EE can get the same effect, right?
Code DD
var aImpl = 0
val a: Int get() = aImpl
fun seta(){
aImpl=5
}
Code EE
var b:Int=0
fun setb(){
b=5
}
Upvotes: 0
Views: 2042
Reputation: 530
When regarding properties the keyword val
means that there is no setter for that property, meaning you can't use the assignment operator =
with it. It doesn't mean, that the returned value has to be constant over time.
Upvotes: 1
Reputation: 200148
In my mind, the val property can't be changed, why doesn't the app cause error?
You must adjust your intuition.
In Kotlin, val
means "read-only property", not "immutable property". Only vals without a custom getter can be considered immutable.
Upvotes: 5
Reputation: 6569
A val
property can return different value every time you call it like this:
private var aImpl = 0
val a: Int get() = aImpl++
Since the return value of mCustomAdapter.getSelectedIndex()
is changing, mySelectedIndex
is obviously changing.
Upvotes: 1