注意:我正在使用Xamarin - 但会在Java Android中接受答案 -
我有一个Android应用程序,其中我有类似的导航到gmail android应用程序。
我有一个左抽屉导航。使用以下选项
当用户启动应用程序时,默认情况下会显示此片段 - 当用户在此活动上并按下后退按钮时应用程序应该关闭
当用户在此片段上并按下它时,它应该返回到资产(收件箱)片段
当用户在此片段上并按下它时,它应该返回到资产(收件箱)片段
这是我在我的活动中启动默认片段的方式
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中的收件箱碎片)
我该怎么做?目前,从导航绘图中加载的所有片段都会添加到堆栈中,当我单击“返回”按钮时,它会转到上一个片段,而不是第一个片段。
答案 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();
}
}
作为另一种解决方法,当您按下后退按钮时,只需使用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();
}
}