如何使用MVVMCross

时间:2017-11-21 01:55:53

标签: android android-fragments xamarin mvvmcross

我是Xamarin的新手,我正在尝试创建我的第一个应用程序。该应用程序将有4个独立模块,具有以下功能:      - 记录清单。      - 用于创建新记录的视图。      - 引用全局模块(配置文件用户)。

关键是,我在Web上发现了一些实现AppCompatActivity,Fragment,Toolbar,ActionBar等的教程。可在此处找到来源:https://github.com/JoeRock11/Xamarin_DesignLibrary

该示例包含三个选项卡,其中包含一个片段,您可以滑动屏幕以更改当前选项卡(类似于Facebook)。我想为我的应用做同样的事情,每个标签都是一个模块。

虽然示例运行完美,但我想实现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;
    }
}

查看(Android项目)

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

现在,我想将我的核心和Android项目改为使用Fragments而不是Activities。

此外,我想知道你对这个特殊情况使用片段而不是活动的意见,因为我只是因为我读过的教程而使用片段。

1 个答案:

答案 0 :(得分:0)

实现此目标的一种方法是在您的应用中使用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。您的活动的viewmodel将托管片段的视图模型作为属性。所以你的所有片段应该从MvxFragment继承,TViewmodel是片段的相应视图模型。该类可以在MvvmCross.Droid.Support.V4库中找到。

第三个步骤是添加一个与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);
}