6

I will set editor action to edittext. My first code is

@BindingAdapter("onEditorAction")
fun bindOnEditorAction(view: TextView, event: () -> Unit) {
    view.setOnEditorActionListener { _, _, _ ->
        event()
        true
    }
}
...
    <EditText
        ...
        app:onEditorAction="@{vm::searchAction}"
        ... />

This is working well

but when I use include tag, I don't know how to pass @{vm::searchAction} as variable like this:

activity.xml:

<?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="vm"
            type="com.example.MyViewModel" />
    </data>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:fillViewport="true"
        android:overScrollMode="never">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

           
            <include
                android:id="@+id/input"
                layout="@layout/view_input_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:action="@{vm::searchAction}"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:text="@={vm.input}" />

        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</layout>

view_input_layout.xml:

<?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="text"
            type="String" />

        <variable
            name="action"
            type="???" />   // **What type for event??**    

    </data>

    <com.google.android.material.card.MaterialCardView
            android:id="@+id/input_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <EditText
                android:id="@+id/input_edit_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:text="@{text}
                app:editorAction=@{action} />  // Passed action will be setted here!

            <TextView
                android:id="@+id/timer_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|end"
                android:layout_marginEnd="20dp"
                tools:text="00:00" />

        </com.google.android.material.card.MaterialCardView>

</layout>

MyViewModel:

class MyViewModel(): ViewModel() {
    
    val input = ObservableField<String>()

    fun searchAction() {
        Log.i("searchAction", "$input")
    }
}

Is there any way to solve this problem?

3
  • 1
    Could you please post full activity.xml: ? Commented Sep 8, 2020 at 6:30
  • added it! thanks @chandmohd Commented Sep 8, 2020 at 7:58
  • I'm looking for the same thing. And i don't want to pass the whole viewModel into my layout. Have you found a solution for this? Commented Oct 13, 2020 at 5:19

3 Answers 3

16

It's an old question, but I answer for others who need help.

Try like this code.

<import type="kotlin.jvm.functions.Function0" />

<import type="kotlin.Unit" />

<variable
    name="action"
    type="Function0&lt;Unit>" />

...
android:onClick="@{() -> action.invoke()}"
...

If your function has many params, you can try like this.

<import type="kotlin.jvm.functions.Function2" />

<import type="kotlin.Unit" />

<variable
    name="action"
    type="Function2&lt;Integer, String, Unit>"/>
Sign up to request clarification or add additional context in comments.

Comments

0

Alternative without imports

Rather than using kotlin function type, you can use the Runnable interface from java as the type.

<include 
  layout="@layout/my_layout"
  action="@{() -> viewModel.myFunction()}"/>

mylayout.xml

<data>
  <variable
      name="action"
      type="Runnable" />
</data
<Button
android:onClick="@{() -> action.run()}"/>

Comments

-1

Try This: activity.xml:

          ......

              <include
                    android:id="@+id/includedInput"
                    layout="@layout/view_input_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    />
            .....

view_input_layout.xml:

<data>
    <variable
        name="text"
        type="String" />

    <variable
        name="vm"
        type="com.example.MyViewModel" />   

</data>

<com.google.android.material.card.MaterialCardView
        android:id="@+id/input_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
         ...
           android:text="@{text}"
           app:onEditorAction="@{vm::searchAction}"
             ... />

        <TextView
            android:id="@+id/timer_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|end"
            android:layout_marginEnd="20dp"
            tools:text="00:00" />

    </com.google.android.material.card.MaterialCardView>

Now inside your activity you can access view_input_layout.xml by includedInput id(from activity.xml)

Initialize viewModel inside your activity something like this

includedInput?.vm = viewModel
inlcudedInput?.text = "hello this is your text"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.