2017-11-21 12 views
2

私はXamarinで新しく、私は最初のアプリケーションを作成しようとしています。このアプリは4つの独立したモジュールを持ち、以下の機能を最低限備えています: - レコードのリスト。 - 新しいレコードを作成するためのビュー。 - グローバルモジュール(プロファイルユーザー)への参照。MVVMCrossを使用してフラグメントをViewModelsに統合するには

要点は、WebでAppCompatActivity、Fragment、Toolbar、ActionBarなどを実装するチュートリアルがいくつか見つかりました。ここにはソースがあります:https://github.com/JoeRock11/Xamarin_DesignLibrary

この例では、3つのタブがあり、その中にフラグメントがあり、画面をスライドさせて現在のタブを変更できます(facebookに似ています)。私は自分のアプリのために同じことをしたい、各タブは1つのモジュールです。

サンプルは完全に動作しますが、私はMVVMCrossフレームワークを実装したいと思いますが、それを達成する方法はわかりません。

これは、フラグメントのサンプルです:

public class Fragment1 : Fragment 
{ 
    public override void OnCreate(Bundle savedInstanceState) 
    { 
     base.OnCreate(savedInstanceState); 
    } 
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     RecyclerView recyclerView = inflater.Inflate(Resource.Layout.Fragment1, container, false) as RecyclerView; 
     SetUpRecyclerView(recyclerView); 
     return recyclerView; 
    } 
    private void SetUpRecyclerView(RecyclerView recyclerView) 
    { 
     var values = GetDataSource(); 
     recyclerView.SetLayoutManager(new LinearLayoutManager(recyclerView.Context)); 
     recyclerView.SetAdapter(new SimpleStringRecyclerViewAdapter(recyclerView.Context, values, Activity.Resources)); 

     recyclerView.SetItemClickListener((rv, position, view) => 
     { 
      //Tasks 
     }); 
    } 
} 

これはMVVMCrossを実装していますが、活動(コアプロジェクト)で作業ViewModelにある:

public class AllPostsViewModel : MvxViewModel 
{ 
    public List<Post> AllPosts { get; set; } 
    public ICommand NavBack 
    { 
     get {return new MvxCommand(() => Close(this));} 
    } 
    public void Init() 
    { 
     Task<List<Bill>> result = Mvx.Resolve<Repository>().GetAllPosts(); 
     result.Wait(); 
     AllPosts = result.Result; 
    } 
} 

ビュー(アンドロイドプロジェクト)

[Activity(Label = "Posts", NoHistory = true)] 
public class AllPostsView : MvxActivity 
{ 
    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.View_AllBills); 
    } 
} 

今、私はコアとアンドロイドのプロジェクトを、アクティビティの代わりにフラグメントを使用するように変更したいと思います。

また、アクティビティではなく、この特定のケースでの使用フラグメントについてのご意見をお聞きしたいと思います。

答えて

0

これを達成する方法の1つは、アプリでViewPagerを使用することです。 まずこれに似たレイアウトを作成します。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/main_content" 
    android:background="@color/bglight" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <android.support.design.widget.TabLayout 
     android:id="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:elevation="4dp" 
     android:background="@color/white" /> 
    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_below="@id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
</RelativeLayout> 

第二ステップは、タブとviewpagerにあなたの断片を追加するホストのアクティビティを作成することです。アクティビティのビューモデルは、フラグメントのビューモデルをプロパティとしてホストします。だからあなたのすべてのフラグメントはMvxFragmentから継承する必要があります。そこには、TViewmodelがフラグメントに対応するビューモデルです。このクラスは、MvvmCross.Droid.Support.V4ライブラリにあります。

第3のステップは、MvxFragmentsで動作するviewpageradapterを追加することです。ちょうどあなたのプロジェクトにこのコードを追加します。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Android.App; 
using Android.Content; 
using Android.Support.V4.App; 
using Java.Lang; 
using MvvmCross.Core.ViewModels; 
using MvvmCross.Droid.Support.V4; 
using Fragment = Android.Support.V4.App.Fragment; 
using FragmentManager = Android.Support.V4.App.FragmentManager; 
using String = Java.Lang.String; 

namespace YourNameSpace 
{ 
    public class MvxViewPagerFragmentAdapter 
     : FragmentStatePagerAdapter 
    { 
     private readonly Context _context; 
     public IEnumerable<FragmentInfo> Fragments { get; private set; } 

     public override int Count 
     { 
      get { return Fragments.Count(); } 
     } 

     public MvxViewPagerFragmentAdapter(
      Context context, FragmentManager fragmentManager, IEnumerable<FragmentInfo> fragments) 
      : base(fragmentManager) 
     { 
      _context = context; 
      Fragments = fragments; 
     } 

     public override Fragment GetItem(int position) 
     { 
      var fragmentInfo = Fragments.ElementAt(position); 
      var fragment = Fragment.Instantiate(_context, 
      Java.Lang.Class.FromType(fragmentInfo.FragmentType).Name); 
      ((MvxFragment)fragment).ViewModel = fragmentInfo.ViewModel; 
      return fragment; 
     } 

     public override ICharSequence GetPageTitleFormatted(int position) 
     { 
      return new String(Fragments.ElementAt(position).Title); 
     } 

     public class FragmentInfo 
     { 
      public string Title { get; set; } 
      public Type FragmentType { get; set; } 
      public IMvxViewModel ViewModel { get; set; } 
     } 
    } 
} 

そして最終ステップは次のようにすべてを配線することです。

protected override void OnCreate(Bundle savedInstanceState) 
{ 
    base.OnCreate(savedInstanceState); 
    SetContentView(Resource.Layout.viewpagerlayout); 

    var viewPager = FindViewById<Android.Support.V4.View.ViewPager>(Resource.Id.viewpager); 

    var fragments = new List<MvxViewPagerFragmentAdapter.FragmentInfo> 
    { 
     new MvxViewPagerFragmentAdapter.FragmentInfo 
     { 
      FragmentType = typeof(AccountsTabAccountsView), 
      Title = ViewModel.AccountTabTitle, 
      ViewModel = ViewModel.AccountsViewModel 
     }, 
     new MvxViewPagerFragmentAdapter.FragmentInfo 
     { 
      FragmentType = typeof(AccountsTabCardsView), 
      Title = ViewModel.CardsTabTitle, 
      ViewModel = ViewModel.CardsViewModel 
     } 
    }; 
    viewPager.Adapter = new MvxViewPagerFragmentAdapter(Activity, SupportFragmentManager, fragments); 
    viewPager.SetCurrentItem(0, true); 
    viewPager.OffscreenPageLimit = 2; 

    var tabLayout = view.FindViewById<TabLayout>(Resource.Id.tabs); 
    tab.TabMode = TabLayout.ModeFixed; 
    tab.TabGravity = TabLayout.GravityFill; 
    tab.FillViewport = true; 
    tab.SetSelectedTabIndicatorColor(ContextCompat.GetColor(Activity, Resource.Color.blue)); 
    tab.SetTabTextColors(ContextCompat.GetColor(Activity, Resource.Color.divider), ContextCompat.GetColor(Activity, Resource.Color.blue));    
    tabLayout.SetupWithViewPager(viewPager); 
} 
+0

「ViewModel.AccountsViewModel」とは何である、「『PostViewModel』は指定されたコンテキストで有効でないタイプであり、」私は私のViewModelを設定すると、私はエラーを取得します。これは私のViewModelの定義です: public class PostViewModel:MvxViewModel – isosa

+0

私は、いくつかのタブの中にfragmentでrecyclerviewを表示する必要があります。この場合は動作しません。 – GvSharma

関連する問題