Alex
Alex

Reputation: 745

Is it possible to bind two variables in xml?

Here point_of_sale_list_item.xml

<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="item"
            type="com.myproject.android.customer.api.model.Merchant" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/imageViewPhoto"
            android:layout_width="90dp"
            android:layout_height="90dp"/>

        <TextView
            android:id="@+id/phoneTextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"/>

    </android.support.constraint.ConstraintLayout>

</layout>

Here root adapter:

public abstract class PreviewSortAdapter extends RealmRecyclerViewAdapter {

    public PreviewSortAdapter(Context context, @Nullable OrderedRealmCollection data, boolean autoUpdate) {
        super(data, true);
        setHasStableIds(true);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, viewType, parent, false);
        setClickHandler(binding);
        return new PreviewBaseViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Object obj = getItem(position);
        PreviewBaseViewHolder previewViewHolder = (PreviewBaseViewHolder) holder;
        ViewDataBinding viewDataBinding = previewViewHolder.getBinding();
        viewDataBinding.setVariable(BR.item, obj);
        viewDataBinding.executePendingBindings(); //binding must be executed immediately
    }

    @Override
    public int getItemViewType(int position) {
        return getLayoutForPosition(position);
    }

    protected abstract int getLayoutForPosition(int position);

    private class PreviewBaseViewHolder extends RecyclerView.ViewHolder {

        private final ViewDataBinding binding;

        private PreviewBaseViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        private ViewDataBinding getBinding() {
            return binding;
        }
    }

}

I use method setVariable() to bind variable "item" with model.

And here concrete child adapter:

public class MapListSortAdapter extends PreviewSortAdapter {

    private static final String TAG = MapListSortAdapter.class.getName();

    public MapListSortAdapter(Context context, OrderedRealmCollection<Merchant> data) {
        super(context, data, true);
    }

    @Override
    protected int getLayoutForPosition(int position) {
        return R.layout.point_of_sale_list_item;
    }

}

In this I adapter I specify only layout xml: point_of_sale_list_item

OK. All work fine.

But now I need to read set phone number from another model. In xml in id android:id=@+id/phoneTextView

So I need to bind second variable. Something like this:

<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="item"
           type="com.myproject.android.customer.api.model.Merchant" />

       <variable
            name="point"
            type="com.myproject.android.customer.api.model.PointOfSale" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">

        <ImageView
            android:id="@+id/imageViewPhoto"
            android:layout_width="90dp"
            android:layout_height="90dp" />

        <TextView
            android:id="@+id/phoneTextView"
            android:layout_width="0dp"
            android:text="@{point.phone}"
            android:layout_height="wrap_content" />

    </android.support.constraint.ConstraintLayout>

</layout>

Here pojo code:

public class PointOfSale {
    private int id;
    private String name;
    private String address;
    private String phone;
    private String email;

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }
}

But of course I get error, because second vairable (point) was not bind:

java.lang.IllegalStateException: failed to analyze: android.databinding.tool.util.LoggedErrorException: Found data binding errors.
****/ data binding error ****msg:Could not find accessor com.myproject.android.customer.api.model.PointOfSale.phone
file:\myProject\app\src\main\res\layout\point_of_sale_list_item.xml
loc:61:28 - 61:38
****\ data binding error ****

So :

  1. Is it possible to bind second varaible?
  2. How I can get data from second variable?

Or maybe create new model that concatenate this 2 models?

Upvotes: 3

Views: 5219

Answers (2)

Adit Chauhan
Adit Chauhan

Reputation: 13

   <data>   
      <variable
                name="object name"
                type="your pojo classpath" />

      <variable
                name="handlers"
                type="your handler class path " /> 
    </data>

working example, link shared below https://www.androidhive.info/android-working-with-databinding/

Upvotes: 0

Alan Todtenkopf
Alan Todtenkopf

Reputation: 472

I've definitely done that. In my case:

<data>
    <variable name="viewModel" type="com.todtenkopf.myfrontpage.viewmodel.favoriteteam.FavoriteTeamVM"/>
    <variable name="matchup" type="com.todtenkopf.myfrontpage.viewmodel.favoriteteam.FavoriteTeamVM.Matchup"/>

You don't show the code for PointOfSale. Is phone a public field or do you have a getPhone accessor? Is sounds more like the problem is along those lines.

Upvotes: 4

Related Questions