is this possible to send parameters to binding events from xml views

3.9k views Asked by At

I'm trying to use DataBinding in Android. But i have a question in my mind.

I want to send edittext's text to binding functions inside xml. I mean; When the login button is clicked, I want to get the current username and password from the xml IDs. Is it possible?

Here what I want:

android:onClick="@{() -> login.onLogin(login_edt_username.text, login_edt_password.text)}"

My Current Usage:

Code:

@Override
protected void onStart() {
    super.onStart();
    binding= DataBindingUtil.setContentView(this,R.layout.activity_login);
}

@Override
public void onLogin() {
    login(binding.loginEdtUserName.getText(),binding.loginEdtPassword.getText());
}

Xml:

<layout>

<data>

    <variable
        name="login"
        type="interfaces.login.LoginInterface" />

</data>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_login"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.friends.LoginActivity">

    <EditText
        android:id="@+id/login_edt_user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Username" />

    <EditText
        android:id="@+id/login_edt_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/login_edt_user_name"
        android:hint="Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_btn_sign_in"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{() -> login.onLogin()}"
        android:layout_below="@+id/login_edt_password"
        android:text="SIGN IN" />

    <Button
        android:id="@+id/login_btn_register"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{() -> login.onRegister()}"
        android:layout_below="@+id/login_btn_sign_in"
        android:text="REGISTER" />

</RelativeLayout>

Thanks in advance.

3

There are 3 answers

4
Georg Grab On BEST ANSWER

This can be solved using 2-way Databinding (available since version 2.1 of the Gradle Plugin).

Alternative 1:

Import android.view.View in your XML:

<data ...>
   <import type="android.view.View"/>
</data>

Then, you will be able to reference some attributes of your Views directly in XML. In Lambda Expressions, like you're using, you can also use the Views like you would in Java. Concretely:

android:onClick="@{() -> login.onLogin(login_edt_username.getText().toString(), login_edt_password.getText().toString())}"

Alternative 2: Using a POJO. Given a POJO modelling your credential information, such as

public class Credentials {
    public String username;
    public String password;
}

, after declaring this model in your XML

<data>
  <variable
     name="login"
     type="interfaces.login.LoginInterface" />
  <variable
     name="credentials"
     type="models.login.Credentials" />
</data>

You could do:

   <!-- .... -->
   <EditText
       android:id="@+id/login_edt_user_name"
       android:layout_width="match_parent"
       <!-- This binds the value of the Edittext to the Model. Note the equals sign! -->
       android:text="@={credentials.username}" />

   <EditText
       android:id="@+id/login_edt_password"
       <!-- Same here -->
       android:text="@={credentials.password}" />

   <!-- ... -->

and finally, to fit your requirement

android:onClick="@{() -> login.onLogin(credentials.username, credentials.password)}"
0
tynn On

When you add an id to a view, this view is accessible by this id from the binding. This includes accessing it from within bindings set in the layout itself.

<EditText
    android:id="@+id/login_edt_user_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Username" />

<EditText
    android:id="@+id/login_edt_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/login_edt_user_name"
    android:hint="Password"
    android:inputType="textPassword" />

<Button
    android:id="@+id/login_btn_sign_in"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="@{() -> login.onLogin(loginEdtUserName.getText(), loginEdtPassword.getText())}"
    android:layout_below="@+id/login_edt_password"
    android:text="SIGN IN" />
0
August W. Gruneisen On

There's some conflict when +id uses the "login_edt_user_name" format. Make sure identifiers use camelCase so they can be properly accessed:

Correct:

android:onClick="@{() -> login.onLogin(loginEdtUserName.getText(), loginEdtPassword.getText())}"

Wrong:

android:onClick="@{() -> login.onLogin(login_edt_user_name.getText(), login_edt_password.getText())}"