Fabian
Fabian

Reputation: 835

Android Data Binding - Reference to view

I use in my new app the data binding library of android. Currently I try to pass a reference of another view to a method.

I have an ImageButton with an onClickListener. In this onClick listener I want to pass a reference of the root view to the method.

<RelativLayout
    android:id="@+id/root_element"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:contentDescription="@string/close_dialog"
        android:src="@drawable/ic_close_212121_24dp"
        android:background="@android:color/transparent"
        android:onClick="@{() -> Helper.doSth(root_element)}"/>

</RelativLayout>

This source code provided above is only an example and not the complete. There are more children and also the image button is not a direct child of the root element. But I think the meaning is clear.

I already tried to pass a reference by specifying the id of the root view (see above). But this doesn't work. If I try to compile this, I get the error, that the type of root_element is not specified.

I also tried to import the generated binding class and access the root element by the public field in it. Also this method doesn't work, since the binding class has to be generated first.

So is there any way to pass a reference of a view to a method? I know that I could pass the id of the root view with @id/root_element, but I don't want that, since I have to find a way to get a reference to this view only with the given id.

Upvotes: 18

Views: 17975

Answers (3)

Pablo Johnson
Pablo Johnson

Reputation: 1092

You should pass the id of the element you want to reference.

<data>

    <variable
        name="viewModel"
        type=".....settings.SettingsViewModel" />
</data>
.
.
.
<Switch
        android:id="@+id/newGamesNotificationSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="@{viewModel.getSubscriptionsValues(newGamesNotificationSwitch)}" />

See that the switch id is newGamesNotificationSwitch and thats what i am passing into getSubscriptionsValues(..) function.

In case your id has some underscores (_) you should pass it using camelcase.

Eg: my_id_with_underscore should be passed as myIdWithUnderscore.

Hope it helps

Upvotes: 1

Matthew Horst
Matthew Horst

Reputation: 2041

The difference between what you have and what you should do is, don't pass the id root_element. Rather, pass through the view as another variable into the layout file.

In my case, I had a switch in my layout, that I wanted to pass as a parameter to a method in my lambda. My code is like this:

MyLayoutBinding binding = DataBindingUtil.inflate(inflater, R.layout.my_layout, parent, true);
binding.setDataUpdater(mDataUpdater);
binding.setTheSwitch(binding.switchFavorite);

Then my layout is like this:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="dataUpdater" type="..."/>
        <variable name="theSwitch" type="android.widget.Switch"/>
        <import type="android.view.View"/>
    </data>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{()->dataUpdater.doSomething(theSwitch)}">
        <Switch
            style="@style/Switch"
            android:id="@+id/switch_favorite"
            ... />
.../>

So as you can see with this, in my code, I get the reference to my switch and pass it in as a variable in the binding. Then in my layout I then have access to it, to pass it through in my lambda.

Upvotes: 8

George Mount
George Mount

Reputation: 20926

You can use root_element, but Android Data Binding camel-cases the names. So, root_element becomes rootElement. Your handler should be:

android:onClick="@{() -> Helper.doSth(rootElement)}"

Upvotes: 78

Related Questions