Reputation: 3525
Consider this snipped:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.test, container, false)
class MyViewHolder(val view: View): RecyclerView.ViewHolder(view) {
init {
view.setOnClickListener {
Log.d("hey", "there")
}
}
}
view.findViewById<RecyclerView>(R.id.files).adapter = object: RecyclerView.Adapter<MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val item = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)
return MyViewHolder(item)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.view.findViewById<TextView>(R.id.text).text = files[position].name
}
override fun getItemCount() = files.size
}
return view
}
onCreateView
creates a local variable view
. The nested class MyViewHolder
also declares a variable called view
. What was unexpected is that the variable view
accessed inside the init
block of MyViewHolder
(where the OnClickListener
is set) is not the one declared in MyViewHolder
, but the outer one. Why?
I would expect the innermost variable declaration would be used.
The class is not declared as an inner
class. Outside variables should not be accesible.
What am I missing?
Upvotes: 0
Views: 42
Reputation: 17701
This is not the case of a nested class, but of a function that returns a class.
If you try to define your class as inner
, you'll actually get an error message:
Modifier 'inner' is not applicable to 'local class'
I'll simplify this example a bit, so the Android part won't interfere:
// This is what you're doing
fun a(): Any {
val a = "a"
class B(val a: String = "b") {
init {
println(a)
}
}
return B()
}
// This is what you think you're doing
class A(val a: String = "a") {
class B(val a: String = "b") {
init {
println(a)
}
}
}
fun main() {
// This refers to function called a
val func = a()
// This refers to a nested class called B
val nestedClass = A.B()
}
If you actually want to refer to the local class properties, use this
Upvotes: 1