1

How can an activity access the instance of the view, after it's been set using SetContentView? I need this because the activity uses a custom view which includes logic and I need this view to sent events to the activity, through a custom event listener that the activity needs to set in the view.

I'm programming with android studio in kotlin. I previously had all the UI control logic in the activity so I was fine, but I am factoring some UI code in a Custom View to re-use it in several activities.

Here is the initialization of the activity

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.custom_view)

        // Here need to access the view instance
        *xxxxxxx*.setCustomViewListener(new CustomView.MyCustomViewListener() {
            @Override
            public void onCancelled() {
                // Code to handle cancellation from the view controls
            }
        });)
    }
}

Here is the view layout

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button android:id="@+id/button_do"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Do" />

    <com.kotlin.app.views.CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/view_custom" />
</FrameLayout>

Here is the custom view class CustomView.kt

class CustomView : FrameLayout, View.OnClickListener {

    constructor(context: Context) : super(context)

    init {
    }

    interface CustomViewListener {
        fun onCancelled()
    }
    private var listener: CustomViewListener? = null

    fun setCustomViewListener(listener: CustomerViewListener) {
        this.listener = listener
    }

Any idea please?

Roland Le Franc
  • 326
  • 1
  • 3
  • 14

2 Answers2

1

How can an activity access the instance of the view, after it's been set using SetContentView?

Step #1: Add an android:id attribute to your root <FrameLayout> element.

Step #2: In onCreate() of your activity, after the setContentView() call, call findViewById() to retrieve the FrameLayout based on the ID that you assigned it in Step #1.

the activity uses a custom view which includes logic and I need this view to sent events to the activity, through a custom event listener that the activity needs to set in the view

You could also just call findViewById() and provide the ID of the custom view (findViewById(R.id.custom_view)).

Note that this covered by pretty much any book on Android app development.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
1

In Kotlin, it's more common to use Kotlin synthetic:

view_custom.setCustomViewListener(...)

Note: you seem to have written your listener implementation in Java, not Kotlin. Since your interface is defined in Kotlin you need something like this:

view_custom.setCustomViewListener(object : CustomView.MyCustomViewListener {
    override fun onCancelled() {
        ...
    }
})

SAM interfaces in Kotlin

Personally I like to use lambdas. Unfortunately you cannot use a lambda as a Kotlin SAM interface. You could however use a typealias instead of an interface:

typealias MyCustomerViewListener = () -> Void

Then you could use this instead:

view_custom.setCustomViewListener {
    // listener code
}
charles-allen
  • 3,891
  • 2
  • 23
  • 35