为一个片段添加多个父活动

Adding multiple parent activities for one fragment

我有一个 片段 需要在用户 登录 时访问注销。因此,我需要一个片段两个活动使用。我正在使用 mvvmcross 4.1 与 Xamarin 和 Monodroid 以及新添加的片段多父功能。我不确定我是否实施正确。

不想使用 ViewPager,因为在查看屏幕时会加载相邻的屏幕。

当我尝试导航到具有两个父活动的片段时出现 Android.Content.ActivityNotFoundException: Unable to find explicit activity class {za.co.app.something.example/examplepcl.droid.views.GetHelpView}; have you declared this activity in your AndroidManifest.xml? 错误。

我一直在查看 GitHub 上的示例项目:https://github.com/MvvmCross/MvvmCross-AndroidSupport/tree/master/Samples/Example.Droid

请评论并告诉我是否应该用我的基础 类 和 viewModels 的代码更新我的问题。

我的片段:

using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using MvvmCross.Binding.BindingContext;
using ExamplePCL.Droid.ModalPopups;
using ExamplePCL.ViewModels;
using MvvmCross.Droid.Shared.Attributes;

namespace ExamplePCL.Droid.Views
{
    [MvxFragment(typeof(LoggedOutTabViewModel), Resource.Id.content_frame)]
    [MvxFragment(typeof(LoggedInTabViewModel), Resource.Id.content_frame)]
    [Register("examplepcl.droid.views.GetHelpView")]
    public class GetHelpView : BaseFragment<GetHelpViewModel>
    {
        protected override int FragmentId => Resource.Layout.gethelp;

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var view = base.OnCreateView(inflater, container, savedInstanceState);

            return view;
        }
    }
}

我的活动:

Activity 1:

using Android.App;
using Android.OS;
using Android.Views;
using ExamplePCL.ViewModels;
using Android.Content.PM;
using Android.Support.V4.Widget;
using ExamplePCL.Droid.Fragments;
using Android.Support.V4.View;
using ExamplePCL.Droid.Interfaces;
using MvvmCross.Droid.Support.V7.Fragging.Caching;
using Android.Widget;
using Android.Support.Design.Widget;
using Android.Support.V4.Content;

namespace ExamplePCL.Droid.Views
{
    [Activity(
        Theme = "@style/AppTheme",
        LaunchMode = LaunchMode.SingleTask,
        ScreenOrientation = ScreenOrientation.Portrait,
        WindowSoftInputMode = SoftInput.AdjustResize | SoftInput.StateAlwaysHidden,
        Name = "examplepcl.droid.views.LoggedInTabView")]
    public class LoggedInTabView : BaseLoggedCachingFragmentActivity<LoggedInTabViewModel>, IDrawerActivity
    {
        TabLayout _globalNavTabLayout;
        int _previousTab;

        #region Activity LifeCycle Handling

        protected override int ContentLayoutId => Resource.Layout.loggedin_base_view;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            if (bundle == null)
                ViewModel.ShowMenu();

            // Setup tabs
            _globalNavTabLayout = FindViewById<TabLayout>(Resource.Id.tabs);
            SetupTabLayout();
        }

        protected override void OnPause()
        {
            _globalNavTabLayout.TabReselected -= GlobalNavTabLayout_TabReselected;
            _globalNavTabLayout.TabSelected -= GlobalNavTabLayout_TabSelected;
            base.OnPause();
        }

        protected override void OnResume()
        {
            _globalNavTabLayout.TabReselected += GlobalNavTabLayout_TabReselected;
            _globalNavTabLayout.TabSelected += GlobalNavTabLayout_TabSelected;
            base.OnResume();
        }

        #endregion

        #region Menu and Toolbar Option Handling

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Android.Resource.Id.Home:
                    DrawerLayout.OpenDrawer(GravityCompat.Start);
                    return true;
            }
            return base.OnOptionsItemSelected(item);
        }

        #endregion

        #region Tab Layout

        void GlobalNavTabLayout_TabSelected(object sender, TabLayout.TabSelectedEventArgs e)
        {
            int tabPosition = e.Tab.Position;

            SetTabPosition(tabPosition);
        }

        void GlobalNavTabLayout_TabReselected(object sender, TabLayout.TabReselectedEventArgs e)
        {
            int tabPosition = e.Tab.Position;

            SetTabPosition(tabPosition);
        }

        void SetupTabLayout()
        {
            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(0).SetCustomView(Resource.Layout.tab_layout_loggedin);
            _globalNavTabLayout.GetTabAt(0).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.icon_my_bill);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(1).SetCustomView(Resource.Layout.tab_layout_loggedin);
            _globalNavTabLayout.GetTabAt(1).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_my_products);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(2).SetCustomView(Resource.Layout.tab_layout_loggedin);
            _globalNavTabLayout.GetTabAt(2).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.btn_launchpadimage);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(3).SetCustomView(Resource.Layout.tab_layout_loggedin);
            _globalNavTabLayout.GetTabAt(3).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_get_help);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(4).SetCustomView(Resource.Layout.tab_layout_loggedin);
            _globalNavTabLayout.GetTabAt(4).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_track);

            //Bring the TabLayout to the front so that it overlays the main content in the
            var tabLayout = FindViewById<LinearLayout>(Resource.Id.linlay_appbar_globalnav);
            tabLayout.BringToFront();

            SetTabPosition(2);
        }

        void SetTabPosition(int index)
        {
            switch (index)
            {
                case 0:
                    ViewModel.ShowMyBillScreenCommand.Execute();
                    break;
                case 1: // My Products
                    ViewModel.ShowMyProductsScreenCommand.Execute();
                    break;
                case 3: // Help
                    ViewModel.ShowGetHelpScreenCommand.Execute();
                    break;
                case 4: // Tracks
                    ViewModel.ShowTrackScreenCommand.Execute();
                    break;
                case 2: // QuickLinks
                    ViewModel.ShowQuickLinksScreenCommand.Execute();
                    break;
            }
        }

        #endregion
    }
}

Activity 2:

using Android.App;
using Android.OS;
using Android.Content.PM;
using ExamplePCL.ViewModels;
using Android.Support.V4.View;
using MvvmCross.Droid.Support.V7.Fragging.Caching;
using ExamplePCL.Droid.Fragments;
using Android.Support.Design.Widget;
using Android.Widget;
using Android.Views;
using Android.Util;
using Android.Content.Res;
using Android.Support.V4.Content;
using System.Threading.Tasks;

namespace ExamplePCL.Droid.Views
{
    [Activity(
        Theme = "@style/AppTheme",
        LaunchMode = LaunchMode.SingleTask,
        ScreenOrientation = ScreenOrientation.Portrait,
        Name = "examplepcl.droid.views.LoggedOutTabView")]
    public class LoggedOutTabView : BaseLoggedCachingFragmentActivity<LoggedOutTabViewModel>
    {
        TabLayout _globalNavTabLayout;
        int _previousTab;

        #region Activity LifeCycle Handling

        protected override int ContentLayoutId => Resource.Layout.loggedout_base_view;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            if (bundle == null)
                ViewModel.ShowMenu();

            // Setup tabs
            _globalNavTabLayout = FindViewById<TabLayout>(Resource.Id.tabs);
            SetupTabLayout();
        }

        protected override void OnPause()
        {
            _globalNavTabLayout.TabReselected -= GlobalNavTabLayout_TabReselected;
            _globalNavTabLayout.TabSelected -= GlobalNavTabLayout_TabSelected;

            base.OnPause();
        }

        protected override void OnResume()
        {
            _globalNavTabLayout.TabReselected += GlobalNavTabLayout_TabReselected;
            _globalNavTabLayout.TabSelected += GlobalNavTabLayout_TabSelected;
            base.OnResume();
        }

        #endregion

        #region Tab Layout

        void GlobalNavTabLayout_TabSelected(object sender, TabLayout.TabSelectedEventArgs e)
        {
            _globalNavTabLayout.TabSelected -= GlobalNavTabLayout_TabSelected;
            _globalNavTabLayout.TabReselected -= GlobalNavTabLayout_TabReselected;

            int tabPosition = e.Tab.Position;

            SetTabPosition(tabPosition);

            _globalNavTabLayout.TabSelected += GlobalNavTabLayout_TabSelected;
            _globalNavTabLayout.TabReselected += GlobalNavTabLayout_TabReselected;
        }

        void GlobalNavTabLayout_TabReselected(object sender, TabLayout.TabReselectedEventArgs e)
        {
            _globalNavTabLayout.TabReselected -= GlobalNavTabLayout_TabReselected;

            int tabPosition = e.Tab.Position;

            SetTabPosition(tabPosition);

            _globalNavTabLayout.TabReselected += GlobalNavTabLayout_TabReselected;
        }


        public void SetupTabLayout()
        {
            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(0).SetCustomView(Resource.Layout.tab_layout);
            _globalNavTabLayout.GetTabAt(0).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_get_help);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(1).SetCustomView(Resource.Layout.tab_layout);
            _globalNavTabLayout.GetTabAt(1).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_track);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(2).SetCustomView(Resource.Layout.tab_layout);
            _globalNavTabLayout.GetTabAt(2).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.btn_launchpadimage);

            _globalNavTabLayout.AddTab(_globalNavTabLayout.NewTab());
            _globalNavTabLayout.GetTabAt(3).SetCustomView(Resource.Layout.tab_layout);
            _globalNavTabLayout.GetTabAt(3).CustomView.FindViewById<ImageView>(Resource.Id.tab_icon).SetImageResource(Resource.Drawable.ico_lock);

            //Bring the TabLayout to the front so that it overlays the main content
            var tabLayout = FindViewById<LinearLayout>(Resource.Id.linlay_appbar_globalnav);
            tabLayout.BringToFront();

            SetTabPosition(2);
        }

        async void SetTabPosition(int index)
        {
            switch (index)
            {
                case 0: // Get Help
                    ViewModel.ShowGetHelpScreenCommand.Execute();
                    break;
                case 1: // Track
                    ViewModel.ShowTrackScreenCommand.Execute();
                    break;
                case 2: // Quick Links
                    ViewModel.ShowQuickLinksScreenCommand.Execute();
                    break;
                case 3: // Login
                    ViewModel.ShowLoginScreenCommand.Execute();
                    break;
            }
        }

        #endregion
    }
}

更新:

问题似乎与我使用库的方式有关 MvvmCross.Droid.Shared.Attributes。如果我只使用一个属性 ([MvxFragment(typeof(LoggedOutTabViewModel), Resource.Id.content_frame)]),我仍然会遇到同样的错误。

但是,如果我使用仅具有一个属性的库 MvvmCross.Droid.Support.V7.Fragging.Attributes,则不会出现任何错误。但显然我不能使用那个库,因为我需要两个属性来进行多个活动。

这更像是一种解决方法而不是解决方案,但您可以这样做:

与其将一个片段 class 称为 GetHelpView,不如创建这三个片段 ->

GetHelpViewLoggedOut

GetHelpViewLoggedIn

GetHelpViewBase

GetHelpViewBase 可以包含 GetHelpViewLoggedInGetHelpViewLoggedOut 之间的所有通用代码,甚至可以重用相同的 ViewModel

不理想,但可能是一种解决方法。

尝试从您的项目中删除 MvvmCross.Droid.Support.V7.Fragging 包,因为它已经 depricated as of Mvx 4.1.4 release. It now forms part of MvvmCross.Droid.Shared package, which you can get off nuget Link. Having both packages installed has been shown to cause