导航类似于Gmail Android应用程序

时间:2017-01-17 14:59:27

标签: android android-fragments xamarin xamarin.android

  

注意:我正在使用Xamarin - 但会在Java Android中接受答案 -

我有一个Android应用程序,其中我有类似的导航到gmail android应用程序。

我有一个左抽屉导航。使用以下选项

  1. 资产(与gmail应用程序收件箱片段一样) -
  2. 当用户启动应用程序时,默认情况下会显示此片段 - 当用户在此活动上并按下后退按钮时应用程序应该关闭

    1. Geofences
    2. 当用户在此片段上并按下它时,它应该返回到资产(收件箱)片段

      1. 通知
      2. 当用户在此片段上并按下它时,它应该返回到资产(收件箱)片段

        这是我在我的活动中启动默认片段的方式

        protected override void OnCreate(Bundle savedInstanceState)
        {
         // Set the initial fragment i.e. AssetListFragment
         var fragment = new AssetListFragment();
         var ft = SupportFragmentManager.BeginTransaction()
                                .Replace(Resource.Id.content_frame, fragment);
        
          ft.Commit();
        
        }
        

        然后,当点击抽屉导航中的某个项目时,我会像下面一样启动片段:

            private void NavigationDrawerItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e)
            {
                Android.Support.V4.App.Fragment fragment = null;
        
                switch (e.MenuItem.ItemId)
                {
                    case Resource.Id.nav_assets:
                        fragment = new AssetListFragment();
                        break;
        
                    case Resource.Id.nav_geofences:
                        fragment = new GeofenceFragment();
                        break;
        
                    case Resource.Id.nav_notifications:
                        fragment = new NotificationsFragment();
                        break;
                }
        
        
                if (fragment != null)
                {
                    var fragmentName = fragment.GetType().Name;
        
                    var fragmentPopped = SupportFragmentManager.PopBackStackImmediate(fragmentName, 0);
        
                    if (!fragmentPopped)
                    {
                        var ft = SupportFragmentManager
                                        .BeginTransaction()
                                        .AddToBackStack(fragmentName)
                                        .Replace(Resource.Id.content_frame, fragment);
        
                        ft.Commit();
                    }
                }
        
                // Close drawer
                _drawerLayout.CloseDrawers();
            }
        

        当用户点击后退按钮时,我已完成以下操作:

            public override void OnBackPressed()
            {
                if (_drawerLayout != null && _drawerLayout.IsDrawerOpen(GravityCompat.Start))
                    _drawerLayout.CloseDrawers();
                else
                {
                    if (SupportFragmentManager.BackStackEntryCount > 0)
                        SupportFragmentManager.PopBackStackImmediate();
                    else
                        base.OnBackPressed();
        
                }
        
            }
        

        我需要做的是总是回到第一个屏幕(在我的情况下是AssetListFragment)(在gmail android app中的收件箱碎片)

        我该怎么做?目前,从导航绘图中加载的所有片段都会添加到堆栈中,当我单击“返回”按钮时,它会转到上一个片段,而不是第一个片段。

1 个答案:

答案 0 :(得分:1)

您将片段添加到堆栈中,当您在第二个或第三个片段并按下后退按钮时,您应该在AssetListFragment

之前弹出所有片段

Android提供API PopBackStackImmediate(id,flag)来导航目标片段。

在我的示例中,FragmentOne是第一个片段,如AssetListFragment

if (FragmentManager.BackStackEntryCount > 0)
{
    FragmentManager.PopBackStackImmediate(new FragmentOne().Id, PopBackStackFlags.None);
}
else
{
    base.OnBackPressed();
}

修改

对于您在堆栈中的要求,片段应存储为1-> 2-> 3-> 1,当我们发现当前片段为1并且单击后退按钮应关闭app时:

Android不提供检测当前片段的API,我们可以添加静态Arraylist来存储您添加的片段。

public static ArrayList myFragments = new ArrayList();

将您替换的每个片段添加到列表中:

 private void Bt1_Click(object sender, EventArgs e)
        {
            FragmentThree fThree = new FragmentThree();
            FragmentManager fm = FragmentManager;
            FragmentTransaction tx = fm.BeginTransaction();
            //tx.Hide(this);
            //tx.Add(Resource.Id.frameLayout1, fThree, "THREE");
            MainActivity.myFragments.Add(fThree);
            tx.Replace(Resource.Id.frameLayout1, fThree, "THREE");  
            tx.AddToBackStack(null);
            tx.Commit();
        }

检查当前片段(如果它是FragmentOne:

Fragment lastFragment = (Fragment)(myFragments[myFragments.Count - 1]);


            if (lastFragment.Tag.Equals("ONE"))
            {
                myFragments.Clear();
                Finish();

            }
            else
            {
                if (FragmentManager.BackStackEntryCount > 0)
                {

                    FragmentManager.PopBackStackImmediate(new FragmentOne().Id, PopBackStackFlags.None);
                    myFragments.RemoveRange(1, myFragments.Count-1);
                }

                else
                {
                    base.OnBackPressed();
                }
            }

enter image description here

作为另一种解决方法,当您按下后退按钮时,只需使用AssetListFragment替换当前片段:

   public override void OnBackPressed()
    {
        if (_drawerLayout != null && _drawerLayout.IsDrawerOpen(GravityCompat.Start))
            _drawerLayout.CloseDrawers();
        else if(FragmentManager.BackStackEntryCount > 1)
        {
            Fragment fragment = new AssetListFragment();
            var ft = SupportFragmentManager
                        .BeginTransaction()
                        .AddToBackStack(null)
                        .Replace(Resource.Id.content_frame, fragment);
            ft.Commit();
        }
        else
        {
             base.OnBackPressed();
        }
    }