MVVMCross中的CustomFragment

时间:2016-05-19 20:57:28

标签: xamarin mvvmcross

我在我的Android应用程序中使用了以下模板,其中导航抽屉有一个选项列表,例如Settings

https://github.com/MvvmCross/MvvmCross-Samples/tree/master/XPlatformMenus

可以从以下网址下载源代码 https://github.com/MvvmCross/MvvmCross-Samples

我想知道如何才能将Settings页面设为DialogCustomFragment,这与下面的图片类似。

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以使用的一种方法是创建Dialog的自定义实现。在您链接到的XPlatformMenus示例后,您可以执行以下操作:

通用自定义对话

此类继承了android Dialog控件,可以与您想要的任何XML / AXML布局一起使用。您可以将它紧密耦合到特定的ViewModel / Layout,也可以使它处理一般的ViewModel类型。以下是泛型类型的示例:

public class CustomDialog : Dialog, IMvxBindingContextOwner
{
    public CustomDialog(Context context, int layout, IMvxViewModel viewModel)
        : this(context, Resource.Style.CustomDialog)
    {
        this.BindingContext = new MvxAndroidBindingContext(context, (context as IMvxLayoutInflaterHolder));
        ViewModel = viewModel;
        Init(layout);
    }

    public CustomDialog(Context context, int themeResId)
        : base(context, themeResId)
    {
    }

    protected CustomDialog(IntPtr javaReference, JniHandleOwnership transfer)
        : base(javaReference, transfer)
    {
    }

    protected CustomDialog(Context context, bool cancelable, IDialogInterfaceOnCancelListener cancelListener)
        : base(context, cancelable, cancelListener)
    {
    }

    protected CustomDialog(Context context, bool cancelable, EventHandler cancelHandler)
        : base(context, cancelable, cancelHandler)
    {
    }

    private void Init(int layout)
    {
        SetContentView(layout);
    }

    public override void SetContentView(int layoutResID)
    {
        var view = this.BindingInflate(layoutResID, null);
        base.SetContentView(view);
    }

    public IMvxBindingContext BindingContext { get; set; }

    public object DataContext
    {
        get { return this.BindingContext.DataContext; }
        set { this.BindingContext.DataContext = value; }
    }

    public IMvxViewModel ViewModel
    {
        get { return this.DataContext as IMvxViewModel; }
        set { this.DataContext = value; }
    }
}

模态的XML布局:

<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary">

    <Button
        android:id="@+id/btn_option"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Show"
        local:MvxBind="Click ShowSettingsCommand"/>

    <Button
        android:id="@+id/btn_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_option"
        android:text="CLOSE"
        local:MvxBind="Click ShowCloseCommand"/>
</RelativeLayout>

CustomDialog风格:

<resources>
  <style name="CustomDialog">
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowNoTitle">true</item>
  </style>
</resources>

自定义演示者

创建自定义演示者以处理导航以显示/隐藏对话框:

public class CustomPresenter : MvxFragmentsPresenter
{
    protected IMvxViewModelLoader MvxViewModelLoader => Mvx.Resolve<IMvxViewModelLoader>();

    CustomDialog _modal;

    public CustomPresenter(IEnumerable<Assembly> AndroidViewAssemblies) : base(AndroidViewAssemblies)
    {
    }

    protected override void ShowActivity(MvxViewModelRequest request, MvxViewModelRequest fragmentRequest = null)
    {
        if (!Intercept(request))
            base.ShowActivity(request, fragmentRequest);
    }

    protected override void ShowFragment(MvxViewModelRequest request)
    {
        if (!Intercept(request))
            base.ShowFragment(request);
    }

    private bool Intercept(MvxViewModelRequest request)
    {
        if (request.ViewModelType == typeof(ThirdViewModel))
        {
            var activity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
            var viewModel = MvxViewModelLoader.LoadViewModel(request, null) as ThirdViewModel;
            _modal = new CustomDialog(activity, Resource.Layout.modal_popup, viewModel);
            _modal.Show();
            return true;
        }

        if (_modal != null)
        {
            _modal.Dismiss();
            _modal = null;
        }
        return false;
    }
}

在设置类中注册自定义演示者:

protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
    var mvxFragmentsPresenter = new CustomPresenter(AndroidViewAssemblies);
    Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxFragmentsPresenter);
    return mvxFragmentsPresenter;
}

<强>视图模型

public class ThirdViewModel : BaseViewModel
{
    private MvxCommand _showSettingsCommand;
    public MvxCommand ShowSettingsCommand =>
        _showSettingsCommand ?? (_showSettingsCommand = new MvxCommand(() => ShowViewModel<HomeViewModel>()));

    private MvxCommand _showCloseCommand;
    public MvxCommand ShowCloseCommand =>
        _showCloseCommand ?? (_showCloseCommand = new MvxCommand(() => ShowViewModel<SettingsViewModel>()));
}