So I'm trying to send a text data from text entered in edit text through another activity with intent. I'm trying to send the text data from HomeActivity
to SearchResultActivity
. However, when I clicked the button that calls the startActivity(intent)
, my application forced closed and I get this exception:
2021-04-27 02:46:30.622 13861-13861/com.dicoding.movieapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dicoding.movieapp, PID: 13861
kotlin.UninitializedPropertyAccessException: lateinit property activityHomeBinding has not been initialized
at com.dicoding.movieapp.home.HomeActivity.onClick(HomeActivity.kt:39)
at android.view.View.performClick(View.java:7500)
at android.view.View.performClickInternal(View.java:7472)
at android.view.View.access$3600(View.java:824)
at android.view.View$PerformClick.run(View.java:28657)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:239)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
I'm quite confused what I did wrong here. This is my code for the home activity. I have already initialized the binding in the onCreate
function but why is it still saying that its uninitialized?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(activityHomeBinding.root)
activityHomeBinding.btnSearch.setOnClickListener(this)
}
override fun onClick(v: View?) {
when (v?.id){
R.id.btn_search -> {
val searchText = activityHomeBinding.editTextSearch.text.toString().trim()
if (searchText == null){
activityHomeBinding.editTextSearch.error = "Field cannot be empty"
} else {
val intent = Intent(this@HomeActivity, SearchResultActivity::class.java)
intent.putExtra(SearchResultActivity.EXTRA_SEARCH,searchText)
startActivity(intent)
}
}
}
And this is the code inside my SearchResultActivity
:
private lateinit var searchResultActivity: ActivitySearchResultBinding
companion object {
const val EXTRA_SEARCH = "extra_search"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
searchResultActivity = ActivitySearchResultBinding.inflate(layoutInflater)
setContentView(searchResultActivity.root)
searchResultActivity.testIntent.text = intent.getStringExtra(EXTRA_SEARCH)
}
The error message points that on line 39 of your HomeActivity class, you're pointing at an uninitialized property. This is because you have defined 2 activityHomeBinding
s with different scopes
class HomeActivity : AppCompatActivity(), View.OnClickListener {
...
lateinit var activityHomeBinding: ActivityHomeBinding <-- 1st one, globally scoped
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater) <-- 2nd one, function-scoped (to onCreate)
setContentView(activityHomeBinding.root)
activityHomeBinding.btnSearch.setOnClickListener(this)
}
override fun onClick(v: View?) {
when (v?.id){
R.id.btn_search -> {
val searchText = activityHomeBinding.editTextSearch.text.toString().trim() <-- this points at 1st one, (i.e. globally scoped)
if (searchText == null){
activityHomeBinding.editTextSearch.error = "Field cannot be empty"
}
...
}
}
}
}
The solution is to simply remove val
from the line where you're inflating the binding. This way, instead of creating a new variable, you're assigning the inflated binding to globally scoped lateinit var activityHomeBinding
which then can be used by your onClick
callback.
So make the change from
override fun onCreate(savedInstanceState: Bundle?) {
...
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
...
}
to
override fun onCreate(savedInstanceState: Bundle?) {
...
activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
...
}