1

ターゲット MvvmCross、Android

目的: ユーザーが動物グループ (両生類、鳥類、魚類、無脊椎動物、哺乳類、爬虫類) を選択できる画面 (ViewModel/View)。グループが選択されると、フラグメント ビューにその動物グループの情報が表示されます。フィールドとレイアウトは動物のグループごとに異なります (例: 魚には羽がありません)。この質問では、動物グループ (かなり静的) を選択しましたが、動物グループのリストは柔軟にしたいと考えています。

シンプルなアプリ構造:

  • MyApp.Core
    • ビューモデル
    • MainViewModel
    • IAnimalGroupViewModel
    • 両生類表示モデル
    • 鳥B表示モデル
    • FishViewModel
  • MyApp.Droid
    • レイアウト
      • メインビュー
      • 両生類フラグメント
      • 鳥のフラグメント
      • フィッシュフラグメント
    • ビュー
      • メインビュー
      • 両生類フラグメント
      • 鳥のフラグメント
      • フィッシュフラグメント

MainView.axml レイアウト ファイルには、表示された動物グループのフラグメント (プレースホルダー) が含まれます。

WPF または WP8 アプリでは、ContentPresenter と Style を使用して、選択した ViewModel をそのビューで自動的に表示できます。

ドロイドでそのようなことをどのように達成できますか?

選択した ViewGroup のタイプに応じて Fragment を設定する MainView.cs で Switch/Case を使用できます。ただし、これは、新しいビューを追加するたびに MainView を変更する必要があることを意味します。

提案/アイデアはありますか?

4

1 に答える 1

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

これが整っていれば、必要なときにフラグメントを作成できます-たとえば

  • ViewModel の ICommand を介して Selection イベントをShowViewModel<TViewModel>呼び出しに変換するとします。
  • そして、これらの ShowViewModel リクエストをインターセプトしてアクティビティに渡すカスタム Mvx プレゼンターがあると仮定します (フラグメント サンプルに似ています) 。

    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大規模な複数ページのアプリでは、おそらくこのメカニズムをより一般的なものにして、いくつかの場所で使用することを検討するでしょう。
于 2013-06-03T16:10:48.877 に答える