如何在 Dialog 中使用数据绑定?

Posted

技术标签:

【中文标题】如何在 Dialog 中使用数据绑定?【英文标题】:How to use data-binding in Dialog? 【发布时间】:2016-04-30 07:15:35 【问题描述】:

我在对话框中实现数据绑定时遇到了麻烦。有可能吗?

下面是我的xml。

<data>

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

<LinearLayout
    android:layout_
    android:layout_>

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

        <LinearLayout
            android:layout_
            android:layout_
            android:orientation="vertical">

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

            <View
                android:layout_
                android:layout_
                android:background="@color/colorPrimaryDark" />

            <TextView
                android:layout_
                android:layout_
                android:gravity="start|center"
                android:padding="15dp"
                android:text="Car Details" />

            <View
                android:layout_
                android:layout_
                android:background="@color/colorPrimaryDark" />

            <TextView
                android:id="@+id/driverName"
                android:layout_
                android:layout_
                android:padding="5dp"
                android:text="@olaBooking.driverName" />

            <TextView
                android:id="@+id/carModel"
                android:layout_
                android:layout_
                android:padding="5dp"
                android:text="@olaBooking.getCarName" />

            <TextView
                android:id="@+id/carNo"
                android:layout_
                android:layout_
                android:padding="5dp"
                android:text="@olaBooking.getCabNo" />

            <TextView
                android:id="@+id/eta"
                android:layout_
                android:layout_
                android:padding="5dp"
                android:text="@olaBooking.getEta" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

我想将上面的布局绑定到一个Dialog中。这怎么可能?下面是我尝试过的 java 代码,但它不起作用

        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);

【问题讨论】:

【参考方案1】:

可以在 Dialog 中使用数据绑定,首先要让绑定在您的 Dialog 上工作,您应该先对其进行充气,然后像这样将其传递给 setContentView。

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

然后就可以传viewModel了:

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

现在你可以看到它在工作了。

【讨论】:

使用绑定设置时对话框无法正确显示,并且可以正常工作 这使我的底部对话框拉伸到整个屏幕 为我工作。谢谢。现在如何从视图模型中隐藏对话框? 要隐藏它,制作一个 MutableLiveData val 的 Bool 并在 FragmentDialog 中订阅它 我们将哪个生命周期所有者设置为绑定?【参考方案2】:

Android Documentation 中所述,您不应将 DataBindingUtil 用于生成的类

您应该使用生成的绑定类的 inflate & bind 方法(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();

能不能简单点?不!

Binding Document 表示DataBindingUtil 类的inflate method

仅当 layoutId 事先未知时才使用此版本。否则, 使用生成的 Binding 的 inflate 方法来确保类型安全 通货膨胀。 DataBindingUtil.inflate(LayoutInflater.from(getContext()),R.layout.my_info_dialog_layout, null, false);

这就像找到绑定生成的类,但我们已经有了类。

改用这个

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

或者如果你想再上课。

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());
    

【讨论】:

谢谢!它也更好,因为它向inflate() 传递的参数更少。 如果我们想让它通用并将其移动到基本对话框有什么建议,那么我想我们只能使用 databindingutil 吗?【参考方案3】:

这是一个带有数据绑定的 AlertDialog 的完整示例:

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();
    


【讨论】:

有时人们只是在没有上下文的情况下发布他们的答案。所以有人(例如我)可能不知道在哪里放置有效的代码。感谢您发布完整的解决方案:)。 @MarekM。是的,就像这家伙***.com/a/66025950/2445763【参考方案4】:

您可以在不调用 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();

【讨论】:

你拯救了我的一天。已收藏!【参考方案5】:
  mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.dialog_select, null, false);
    setContentView(mBinding.getRoot());
    SelectDialogBean data = new SelectDialogBean();
    mBinding.setData(data);

【讨论】:

应用此解决方案时,我注意到建议的LayoutInflater.from(getContext()) 在对话框中为我提供了与使用数据绑定之前不同的主题。我最终使用了对话框提供的LayoutInflater,如下所示:dialog.getLayoutInflater()LayoutInflater.from(dialog.getContext())【参考方案6】:

如果您不想扩展 Dialog,另一种可能的解决方案是:

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();

希望对你有帮助。

【讨论】:

【参考方案7】:

**

您应该在 DialogFragment 的上下文中使用活动。

**

在 DialogFragment 中使用数据绑定时的问题是主题不尊重暗模式颜色。如果您对此有疑问,请在LayoutInflater.from(context) 中使用LayoutInflater.from(activity)

【讨论】:

【参考方案8】:

如果您的对话框缩小,试试这个

我尝试了@Dullahan 的回答,但对话框似乎奇怪地缩小了。 于是我尝试了另一种方法,终于找到了解决方案。

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

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/root"
        android:layout_
        android:layout_>

        <!-- ... -->

    </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))
    

【讨论】:

以上是关于如何在 Dialog 中使用数据绑定?的主要内容,如果未能解决你的问题,请参考以下文章

准备好 Dialog ViewModel 绑定,调用 Dialog 并在 MVVM 中从它返回数据

自定义组件之间的双向绑定

如何在BackboneJS中绑定视图元素上的事件?

element-ui 点击编辑弹出dialog组件中select组件绑定值改变,但是不触发change事件

Vue中使用element-ui 给按钮绑定一个单击事件,实现点击按钮就弹出一个dialog对话框

如何在角度中使用单个组件作为页面和 MatDialog