Home > Net >  onClick method is not called from .xml binding expression with dataBinding
onClick method is not called from .xml binding expression with dataBinding

Time:12-05

I'm trying to call a function which is in the "MainActivity.kt" from "content_main.xml" by usage of a binding expression in the onClick (what are these actually called, attribute?) of a button.

Problem is, they never get called when I press eighter of the buttons.

That's how the code passage looks like in the "content_main.xml" file (I've left out unnecessary code for better readability):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable
        name="viewModel"
        type="com.ronnabyte.ntatools.model.FuelViewModel" />

    <variable
        name="activity"
        type="com.ronnabyte.ntatools.MainActivity" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    ...

    <Button
        android:id="@ id/clear_required_fuel_btn"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="@{()->activity.clearRequiredFuel()}"
        android:text="@string/clear_fuel_on_board"
        app:icon="@drawable/ic_baseline_delete_24"
        app:layout_constraintBottom_toBottomOf="@ id/required_fuel_ed"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/required_fuel_ed"
        app:layout_constraintTop_toTopOf="@ id/required_fuel_ed" />

    ...

    <Button
        android:id="@ id/clear_remaining_fuel_btn"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="@{()->activity.clearRemainingFuel()}"
        android:text="@string/clear_fuel_on_board"
        app:icon="@drawable/ic_baseline_delete_24"
        app:layout_constraintBottom_toBottomOf="@ id/remaining_fuel_ed"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@ id/remaining_fuel_ed"
        app:layout_constraintTop_toTopOf="@ id/remaining_fuel_ed" />

    ...

</androidx.constraintlayout.widget.ConstraintLayout>

And the code in the "MainActivity.kt":

package com.ronnabyte.ntatools

import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.LifecycleOwner
import com.ronnabyte.ntatools.databinding.ActivityMainBinding
import com.ronnabyte.ntatools.model.FuelViewModel

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding
private val viewModel: FuelViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

    setSupportActionBar(binding.toolbar)

    binding.fab.setOnClickListener {
        viewModel.calculateFuelUplift()
    }
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.menu_main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    return when (item.itemId) {
        R.id.action_settings -> true
        else -> super.onOptionsItemSelected(item)
    }
}

fun clearRequiredFuel() {
    Log.d("MainActivity", "ClearRequiredFuel has been called.")
    binding.contentMain.apply {
        requiredFuelUpliftTv.text = ""
        requiredFuelEd.text.clear()
        requiredFuelEd.requestFocus()
    }
}

fun clearRemainingFuel() {
    Log.d("MainActivity", "ClearRemainingFuel has been called.")
    binding.contentMain.apply {
        requiredFuelUpliftTv.text = ""
        remainingFuelEd.text.clear()
        requiredFuelEd.requestFocus()
    }
}

Any help is appreciated, many thanks.

CodePudding user response:

make these little changes to your code:

private lateinit var binding: ActivityMainBinding
private val viewModel: FuelViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
binding
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater) //<--
    setContentView(binding.root) //<--
    setSupportActionBar(binding.toolbar)

CodePudding user response:

Add this line in your onCreate method:

binding.activity = this

Demo code below:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        // without this line, test() will not called
        binding.activity = this
    }

    fun test() {
        Log.d("test", "test")
    }
}
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="activity"
            type="com.example.myapplication.MainActivity" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> activity.test()}"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  • Related