1

Target MvvmCross, AndroidВыбор фрагмента Просмотр в зависимости от выбранного элемента типа ViewModel

Цель: Экран (ViewModel/View), где пользователь может выбрать группу животных (земноводные, птицы, рыбы, беспозвоночные, млекопитающие, рептилии). Когда группа будет выбрана, фрагменты будут отображать информацию для этой группы животных. Поля и макет отличаются друг от друга на группу животных (например, у рыб нет крыльев). Хотя для этого вопроса я выбрал для группы животных (что довольно статично), нужно, чтобы группы групп списка были гибкими.

Упрощенная структура приложения:

  • MyApp.Core
    • ViewModels
    • MainViewModel
    • IAnimalGroupViewModel
    • AmphibiansViewModel
    • BirdsBViewModel
    • FishViewModel
  • MyApp.Droid
    • Layout
      • MainView
      • AmphibiansFragment
      • BirdsFragment
      • FishFragment
    • Просмотров
      • MainView
      • AmphibiansFragment
      • BirdsFragment
      • FishFragment

Файл макета MainView.axml будет содержать (заполнитель для) фрагмент отображаемой группы животных.

В WPF или WP8 приложении я мог бы использовать ContentPresenter и стиль для автоматического отображения выбранного ViewModel с его представлением.

Как я мог достичь чего-то подобного в Droid?

Я мог бы использовать коммутатор/корпус в MainView.cs, который устанавливает Фрагмент в соответствии с типом выбранной группы ViewGroup. Но это означает, что я должен модифицировать MainView каждый раз, когда добавляю новый вид.

Любые предложения/идеи?

+0

Один раз ответили ... но в моем уме есть альтернативный подход, основанный на использовании только XML ... не совсем поняли, что это такое ... – Stuart

ответ

1

В настоящее время MvvmCross не предоставляет какой-либо механизм автоматической навигации для фрагментов таким же образом, как и для операций.

Однако в вашем случае использования, если вы хотите использовать навигационный подход, вы можете автоматически создать аналогичный тип автоматического механизма поиска/навигации.

Чтобы сделать это, корень простого разработчика, вероятно, будет использовать отражение, чтобы найти поиск по словарю для всех фрагментов

var fragments = from type in this.GetType().Assembly.GetTypes() 
       where typeof(IAnimalGroupView)..sAssignableFrom(type) 
       where type.Name.EndsWith("Fragment") 
       select type; 
var lookup = fragments.ToDictionary(
        x => x.Name.Substring(0, x.Name.Length - "Fragment".Length) 
           + "ViewModel", 
        x => x); 

Имея это в месте, вы можете затем создать фрагменты, когда они необходимы - например

  • при условии, что вы преобразовать событие Selection через ICommand на ViewModel в ShowViewModel<TViewModel> вызова
  • и при условии, что у вас есть ведущий заказ MVX который перехватывает эти запросы ShowViewModel и передает их деятельности (по аналогии с Fragment sample) - например

    public class CustomPresenter 
        : MvxAndroidViewPresenter 
    { 
        // how this gets set/cleared is up to you - possibly from `OnResume`/`OnPause` calls within your activities. 
        public IAnimalHostActivity AnimalHost { get; set; } 
    
        public override void Show(MvxViewModelRequest request) 
        { 
         if (AnimalHost != null && AnimalHost.Show(request)) 
          return; 
    
         base.Show(request); 
        } 
    } 
    
  • тогда ваша деятельность может реализовать Show используя что-то вроде:

    if (!lookup.ContainsKey(request.ViewModelType.Name)) 
        return false; 
    
    var fragmentType = lookup[request.ViewModelType.Name]; 
    var fragment = (IMvxFragmentView)Activator.Create(fragmentType); 
    fragment.LoadViewModelFrom(request); 
    
    var t = SupportFragmentManager.BeginTransaction(); 
    t.Replace(Resource.Id.my_selected_fragment_holder, fragment); 
    t.Commit(); 
    return true; 
    

Примечания:

  • , если вы не используете ShowViewModel здесь то, очевидно, это тот же самый подход может отрегулировать ... но этот ответ должен был предложить что-то ...
  • в более крупном многостраничном приложении, вероятно, вы захотите сделать этот механизм IAnimalHostActivity более универсальным и использовать его в нескольких местах.