MVVMCross中的CustomFragment [英] CustomFragment in MVVMCross
问题描述
我在Android应用程序中使用了以下模板,该模板的导航抽屉中包含诸如Settings
之类的选项列表.
I have used the following template in my Android application which has navigation drawer has a list of options such as Settings
.
https://github.com/MvvmCross/MvvmCross-Samples/tree /master/XPlatformMenus
可以从以下URL下载源代码 https://github.com/MvvmCross/MvvmCross-Samples
Source code could be downloaded from the following url https://github.com/MvvmCross/MvvmCross-Samples
我想知道如何将Settings
页面制作为Dialog
或CustomFragment
,其外观类似于下图.
I wonder how could I able to make Settings
page as a Dialog
or CustomFragment
which will look like similar to following image.
推荐答案
您可以使用的一种方法是创建Dialog
的自定义实现.按照您链接到的 XPlatformMenus 示例,您可以执行以下操作:
One approach that you could make use of is to create a custom implementation of Dialog
. Following the XPlatformMenus sample you linked to, you could implement something as follows:
常规自定义对话框
此类继承了android Dialog
控件,并且可以与所需的任何XML/AXML布局一起使用.您可以将其紧密耦合到特定的ViewModel/Layout上,也可以使其处理通用的ViewModel类型.这是通用类型的示例:
This class inherits android Dialog
control, and can be used with any XML/AXML layout you want. You could tightly couple it to a particular ViewModel/Layout or you can make it handle a generic ViewModel type. Here is an example of the generic type:
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样式:
CustomDialog style:
<resources>
<style name="CustomDialog">
<item name="android:windowIsFloating">true</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
自定义演示者
创建自定义演示者以处理导航以显示/隐藏对话框:
Create a custom presenter to handle the navigation to show/hide the dialog:
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;
}
}
在设置类中注册您的自定义演示者:
Register your custom presenter in the setup class:
protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
var mvxFragmentsPresenter = new CustomPresenter(AndroidViewAssemblies);
Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxFragmentsPresenter);
return mvxFragmentsPresenter;
}
ViewModel
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>()));
}
这篇关于MVVMCross中的CustomFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!