Kotlin OnClick Listener
Solution 1
I think the problem here is that you're calling val buttonClick= findViewById<Button>(R.id.button)
in BaseActivity.onCreate
, which is called in MainActivity.onCreate
before you call setContentView
... So the view isn't initialized yet, and you aren't subscribed for click events.
You can attach onClickListener
in MainActivity
, or if you still want to do it from your BaseActivity
you can make additional initViews
method and call it after setContentView
:
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initViews()
}
}
open class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
protected fun initViews() {
val buttonClick= findViewById<Button>(R.id.button)
buttonClick?.setOnClickListener {
Toast.makeText(this@BaseActivity, "Click...", Toast.LENGTH_LONG).show()
}
}
}
Solution 2
You need to move the code of your listener in your MainActivity
.
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val buttonClick= findViewById<Button>(R.id.button)
buttonClick?.setOnClickListener {
Toast.makeText(this@MainActivity, "Click...", Toast.LENGTH_LONG).show()
}
}
Because you are defining your listener in your BaseActivity's onCreate your findViewById<Button>(R.id.button)
is effectively null due to the fact that setContentView(R.layout.activity_main)
is called after.
Related videos on Youtube
Ankit Tale
An Mobile Developer by Profession on the way to become Full Stack Developer, an tech enthusiast who love to explore technology read magazine. I am here to answer the question and help the budding developer with an experience and helpful knowledge
Updated on June 04, 2022Comments
-
Ankit Tale almost 2 years
I am trying to get Toast from UI defined in MainActivity and writing a code in Base Activity for onClick Listener. As per requirement I had define my base class as open but still I am not getting Toast
Here is code
BaseActivity
open class BaseActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val buttonClick= findViewById<Button>(R.id.button) buttonClick?.setOnClickListener { Toast.makeText(this@BaseActivity, "Click...", Toast.LENGTH_LONG).show() } } }
MainActivity
class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" tools:layout_editor_absoluteY="81dp"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="18dp" android:layout_marginBottom="16dp" android:layout_marginEnd="16dp" android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:text="Hello World!" app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.409" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="190dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </android.support.constraint.ConstraintLayout>
Can you tell what wrong with code how can I get a click from it
-
Sweeper almost 6 yearsDid you forget to call
setContentView
?
-
-
egorikem almost 6 yearsPersonally, i think this is a bad approach. There is quite a possibility that you will forget to call
initViews
at some point that nothing will work, leading you to hours of investigation. Furthermore, if you want to fix that and defineinitViews
as abstract, there is no point in having this in separate method in first place: just make variable abstract. See my answer for more details -
egorikem almost 6 yearsIt does solve the issue, however it does not suit logic he wanted to maintain: all activities inherited from base one should behave in the same way
-
Enzokie almost 6 years@GeorgySavatkov yes that's correct although you have it answered already I'll just leave the credit to yours :)
-
Demigod almost 6 yearsWhile this is not the best approach, it doesn't force you to use
initViews
, while havingabstract val button
will force every activity that will extendBaseActivity
to implement it. Furthermore, your question doesn't solve the core problem. -
egorikem almost 6 yearsHold on, the question itself intended, that he wants to have a base activity, which incapsulates some logic (every activity extended from that one should have the same logic), therefore "force every activity" is exactly what he wants
-
Enzokie almost 6 yearsWait I notice a slight problem here >
BaseActivity.onCreate()
will be called first beforeMainActivity.onCreate()
which stills make buttonClick null.