2016-05-19 1 views
0

Я использовал следующий шаблон в своем приложении для Android, у которого есть навигационный ящик, который имеет список опций, таких как Settings.CustomFragment в MVVMCross

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

Исходный код можно загрузить по следующей ссылке https://github.com/MvvmCross/MvvmCross-Samples

Интересно, как бы я смог сделать Settings страница как Dialog или CustomFragment, который будет выглядеть похоже на следующее изображение.

enter image description here

+0

, как мы делаем это в наше приложение использует пользовательский выступающему. Ведущий содержит ссылку на текущую активность, и мы добавили методы DisplayDialog и DismissDialog, которые добавляют «Фрагмент» в текущую активность. Это сообщение в блоге о персонализированных докладчиках - это хорошее место для начала: http://gregshackles.com/presenters-in-mvvmcross-a-primer/ – pnavk

ответ

2

Один подход, который можно использовать, чтобы создать пользовательскую реализацию Dialog. После XPlatformMenus образца вы связаны, вы могли бы реализовать что-то выглядит следующим образом:

Generic Выборочной Dialog

Этот класс наследует андроид 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> 

Пользовательские Presenter

Создание пользовательского выступающему для навигации, чтобы показать/скрыть Диалог:

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

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>())); 
} 
+0

У меня только появился шанс реализовать логику, которую вы предоставили, но, к сожалению, я мог не в состоянии его получить. Вот github: https://github.com/texas16/Dialog – hotspring

+1

@hotspring. Кажется, что проблемы находятся в строке 36 и строке 39 CustomPresenter.cs, которая должна использовать тип ViewModel, то есть 'ThirdViewModel' не' ThirdFragment . Кроме того, в вашем Setup.cs вам нужно вернуть экземпляр «CustomPresenter». Вы можете сделать это в строке 43, заменяя 'MvxFragmentsPresenter' своим пользовательским типом презентатора' CustomPresenter'. – Plac3Hold3r