91

I am having trouble in implementing databinding in a Dialog. Is it possible?

Below is my xml.

<data>

    <variable
        name="olaBooking"
        type="com.example.myapp.viewmodels.ViewModel" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.CardView
        android:id="@+id/cv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:elevation="4dp"
        android:padding="15dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/colorPrimary"
                android:gravity="center"
                android:padding="15dp"
                android:text="OLA Cab Booked !"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

            <View
                android:layout_width="match_parent"
                android:layout_height="2dp"
                android:background="@color/colorPrimaryDark" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="start|center"
                android:padding="15dp"
                android:text="Car Details" />

            <View
                android:layout_width="match_parent"
                android:layout_height="2dp"
                android:background="@color/colorPrimaryDark" />

            <TextView
                android:id="@+id/driverName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="@{olaBooking.driverName}" />

            <TextView
                android:id="@+id/carModel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="@{olaBooking.getCarName}" />

            <TextView
                android:id="@+id/carNo"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="@{olaBooking.getCabNo}" />

            <TextView
                android:id="@+id/eta"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="@{olaBooking.getEta}" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

I want to bind the above layout in a Dialog. How is it possible? Below is my java code i tried but it's not working

        dialog.setContentView(R.layout.dialog_ola_booking_confirmed);
    DialogOlaBookingConfirmedBinding binding = DataBindingUtil.inflate(
            LayoutInflater.from(dialog.getContext()),
            R.layout.dialog_ola_booking_confirmed,
            (ViewGroup) dialog.findViewById(R.id.cv),
            false);
    ViewModel viewModel = new ViewModel(this, event.olaBooking);

9 Answers 9

105

It is possible to use databinding in a Dialog, first to get the binding working on your Dialog you should inflate it first and pass it to the setContentView like this.

DialogOlaBookingConfirmedBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout. dialog_ola_booking_confirmed, null, false);
setContentView(binding.getRoot());

Then you can pass the viewModel:

binding.setViewModel(new ViewModel(this, event.olaBooking));

And now you can see it working.

Sign up to request clarification or add additional context in comments.

6 Comments

dialog is not properly showing when set using binding and it works with normal way
this made my bottomsheet dialog stretched to whole screen
worked for me. thanks. how to hide dialog from viewmodel now?
To hide it make a MutableLiveData val of Bool and subscribe to it inside the FragmentDialog
Which lifecycleOwner to we set to the binding?
|
45

You should not use DataBindingUtil for generated classes as said in Android Documentation

You should use generated binding class's inflate & bind method (MyDialogBinding.inflate).

public void showDialog(final Context context) {
    Dialog dialog = new Dialog(context);
    MyDialogBinding binding = MyDialogBinding.inflate(LayoutInflater.from(context));
    dialog.setContentView(binding.getRoot());
    dialog.show();
}

Can it be simpler? No!

Binding Document says for DataBindingUtil class's inflate method.

Use this version only if layoutId is unknown in advance. Otherwise, use the generated Binding's inflate method to ensure type-safe inflation. DataBindingUtil.inflate(LayoutInflater.from(getContext()),R.layout.my_info_dialog_layout, null, false);

This is like finding binding generated class, when we have class already.

Instead use this

MyDialogBinding binding = MyDialogBinding.inflate(LayoutInflater.from(context));

or if you want make another class.

public class MyDialog extends Dialog {
    public MyDialog(@NonNull Context context) {
        super(context);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyDialogBinding binding = MyDialogBinding.inflate(LayoutInflater.from(getContext()));
        setContentView(binding.getRoot());
    }
}

2 Comments

Thank you! It's also nicer because it passes fewer arguments to inflate().
any suggestions if we want to make it generic and move it to base dialog then i guess we can use databindingutil only ?
36

Here is a full example of an AlertDialog with Databinding:

import android.app.Dialog;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;


public class MyDialog extends DialogFragment {

    private static final String KEY_MY_INFO = "KEY_MY_INFO";

    private String myInfo;

    public static MyDialog newInstance(String myInfo) {
        MyDialog dialog = new MyDialog();
        Bundle bundle = new Bundle();
        bundle.putString(KEY_MY_INFO, myInfo);
        dialog.setArguments(bundle);
        return dialog;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myInfo = getArguments().getString(KEY_MY_INFO);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        FragmentActivity activity = getActivity();
        
        MyInfoBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()),
                R.layout.my_info_dialog_layout, null, false);

        binding.setMyInfo(myInfo);

        return new AlertDialog.Builder(activity, R.style.AppCompatAlertDialogStyle)
                .setView(binding.getRoot())
                .create();
    }

}

2 Comments

Sometimes people just post their answers without a context. So somebody (me for example) may have no clue on where to put the code that worked. Thank you for posting a full solution :).
@MarekM. yep, just like this guy stackoverflow.com/a/66025950/2445763
17

You can do the same without calling getRoot().

View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_delete_confirmation, null, false);

mBinding = DialogDeleteConfirmationBinding.bind(view);

mBinding.setViewModel(viewModel);

builder.setView(view);

builder.create();

Comments

12
  mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.dialog_select, null, false);
    setContentView(mBinding.getRoot());
    SelectDialogBean data = new SelectDialogBean();
    mBinding.setData(data);

1 Comment

When applying this solution, I noticed the suggested LayoutInflater.from(getContext()) gives me a different theme inside the dialog than before using data binding. I ended up using the LayoutInflater the dialog provides like so: dialog.getLayoutInflater() or LayoutInflater.from(dialog.getContext())
3

If your dialog shrink, Try this

I tried @Dullahan's answer, however the dialog seemed to shrink strangely. So I tried another ways, finally found solution.

<layout
    xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/root"
        android:layout_width="300dp"
        android:layout_height="500dp">

        <!-- ... -->

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class CustomDialog(context: Context) : Dialog(context) {
    private lateinit var binding: CustomDialogBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.custom_dialog)
        binding = CustomDialogBinding.bind(findViewById(R.id.root))
    }
}

Comments

2

If you don't want to extend Dialog, another possible solution could be:

Dialog dialog = new Dialog(this); // where "this" is the context

YourClassNameBinding binding = DataBindingUtil.inflate(dialog.getLayoutInflater(), R.layout.your_layout, null, false);
binding.setYourData(yourData);

dialog.setContentView(binding.getRoot());
dialog.show();

Hope it helps.

Comments

1

You should use activity inside of context for DialogFragment.

The problem when you use databinding in DialogFragment is theme is not respect to dark mode colors. If you have problem with this use LayoutInflater.from(activity) inside of LayoutInflater.from(context)

Comments

-1

val bottomViewBinding :AddProductNoPositionBottomPupUpBinding = AddProductNoPositionBottomPupUpBinding.inflate(layoutInflater) bottomSheetDialog = BottomSheetDialog(this , R.style.BottomSheetDialoTheme) bottomSheetDialog.setContentView(bottomViewBinding.root) bottomSheetDialog.show() bottomViewBinding.productDataBinding = product

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

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.