android - 如何使用 MVVMCross 将 Fragments 集成到 ViewModels 中

标签 android android-fragments xamarin mvvmcross

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

关键是,我在网上找到了一些实现AppCompatActivity、Fragment、Toolbar、ActionBar等的教程。来源可以在这里找到:https://github.com/JoeRock11/Xamarin_DesignLibrary

示例中包含三个标签页,标签页里面有一个fragment,可以滑动屏幕改变当前标签页(类似于facebook)。我想为我的应用程序做同样的事情,每个选项卡都是一个模块。

虽然示例运行完美,但我想实现 MVVMCross 框架,但我不知道如何实现它。

这是一个 fragment 示例:

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 但与 Activity (核心项目)一起工作的 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 而不是 Activity。

此外,我想知道您对在这种特殊情况下使用 fragment 而不是 Activity 的看法,因为我只是在阅读教程时才使用 fragment 。

最佳答案

实现此目的的一种方法是在您的应用中使用 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>

第二步是创建一个主机 Activity ,将您的 fragment 添加到选项卡和viewpager。您 Activity 的 View 模型会将 fragment 的 View 模型托管为属性。所以你所有的 fragment 都应该从 MvxFragment 那里继承 TViewmodel 是 fragment 对应的 View 模型。此类可以在 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);
}

关于android - 如何使用 MVVMCross 将 Fragments 集成到 ViewModels 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47404011/

相关文章:

android - 错误 = TooManyMessages GCM

ios - 如何将汉堡菜单添加到 Xamarin iOS 项目?

android - 无法找到保存的图像

java - PhonecallReceiver 无法在 android studio 上运行?

android - 使用小部件为 Android 应用评分

android - ViewPager 中的全屏广告

android - Android fragment 中的动态背景

c# - 我可以在 Xamarin.Forms 中以编程方式更改 styles.xml 吗?

java - 将 Android 应用程序安装限制在 Android 手机上

java - 在自定义 View 类中访问 FragmentManager