I can't reach any class member from a nested class in Kotlin

ClassKotlinScopeMember

Class Problem Overview


I want to access a member of the MainFragment class from PersonAdapter class but none of them are available. I tried making both the classes and the members public and private also but so far nothing worked. I guess I'm missing something obvious but I just can't figure it out.

class MainFragment : Fragment() {
    lateinit var personAdapter: PersonAdapter
    lateinit var personListener: OnPersonSelected
    private var realm: Realm by Delegates.notNull()
    lateinit var realmListener: RealmChangeListener<Realm>

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val v = inflater.inflate(R.layout.fragment_main, container, false)
        return v
    }

    class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
        var localPersonList = personList

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

            holder.itemView.setOnClickListener {
                Toast.makeText(context, "click", Toast.LENGTH_SHORT).show()
                //I want to reach personListener from here
            }
        }

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

Class Solutions


Solution 1 - Class

In Kotlin, nested classes cannot access the outer class instance by default, just like nested static classes can't in Java.

To do that, add the inner modifier to the nested class:

class MainFragment : Fragment() {
    // ...

    inner class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
        // ...
    }
}

Note that an inner class holds a reference to its containing class instance, which may affect the lifetime of the latter and potentially lead to a memory leak if the inner class instance is stored globally.

See: Nested classes in the language reference

Solution 2 - Class

In Kotlin, there are 2 types of the nested classes.

  1. Nested Class
  2. inner Class

Nested class are not allowed to access the member of the outer class.

If you want to access the member of outer class in the nested class then you need to define that nested class as inner class.

class OuterClass{

    var name="john"

    inner class InnerClass{
      
       //....
    }

}

Solution 3 - Class

  • Add inner
  • Note that Android Studio's Code completion(IntelliSense) doesn't work right inside the inner class
class OuterClass {
    val outerVariable = "Hello, World!"

    inner class InnerClass {
        // Code completion doesn't work here

        val innerVariable = outerVariable // Code completion work

        fun innerFunction() {
            // Code completion work
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionftibi93View Question on Stackoverflow
Solution 1 - ClasshotkeyView Answer on Stackoverflow
Solution 2 - ClassAaRiFView Answer on Stackoverflow
Solution 3 - ClassJoonsooView Answer on Stackoverflow