@Hans Baum 不要将第一个片段添加到后台堆栈,而是尝试使用此代码,
@Override
public void onBackPressed() {
if(mBottomNavigationView.getSelectedItemId () != R.id.ic_home)
{
mBottomNavigationView.setSelectedItemId(R.id.ic_home);
}
else
{
super.onBackPressed();
}
}
如果您在主片段中,此代码将退出您的活动,否则,如果您在任何其他片段中,它将转到主片段。
所以不需要 addToBackStack() 。所以你的 serFragment() 方法应该是,
private void setFragment(Fragment fragment, String tag) {
FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.replace(R.id.container, fragment, tag);
transaction.commit();
}
希望能帮助到你。
请注意,在您的代码中,您从未将 false 分配给 isFirstFragment,因此我假设所有片段都添加到 backstack 中,这非常消耗内存。
UPDATE:
由于您的要求不同。如您所愿Instagra我喜欢选项卡,我希望这个实现对您有所帮助。
Deque<Integer> mStack = new ArrayDeque<>();
boolean isBackPressed = false;
private void setBottomNavigationView() {
mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_home:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_home);
}
isBackPressed = false
setFragment(HomeFragment.newInstance(), HOME_FRAGMENT);
return true;
case R.id.ic_search:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_search);
}
isBackPressed = false
setFragment(SearchFragment.newInstance(), SEARCH_FRAGMENT);
return true;
case R.id.ic_circle:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_circle);
}
isBackPressed = false
setFragment(ShareFragment.newInstance(), SHARE_FRAGMENT);
return true;
default:
return false;
}
}
});
mBottomNavigationView.setOnNavigationItemReselectedListener(new
BottomNavigationView.OnNavigationItemReselectedListener() {
@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
}
});
mBottomNavigationView.setSelectedItemId(R.id.ic_home);
pushFragmentIntoStack(R.id.ic_home);
}
private void pushFragmentIntoStack(int id)
{
if(mStack.size() < 3)
{
mStack.push(id);
}
else
{
mStack.removeLast();
mStack.push(id);
}
}
private void setFragment(Fragment fragment, String tag) {
FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.replace(R.id.container, fragment, tag);
transaction.commit();
}
@Override
public void onBackPressed() {
if(mStack.size() > 1)
{
isBackPressed = true;
mStack.pop();
mBottomNavigationView.setSelectedItemId(mStack.peek());
}
else
{
super.onBackPressed();
}
}
我使用 deque 来存储单击选项卡的顺序,因为有 3 个选项卡 deque 大小为 3 。按回键时,它将弹出堆栈并转到该选项卡。如果堆栈中没有项目,它将退出活动。
重要的提示:在这种情况下,不要将片段添加到后台堆栈,因为当我切换选项卡时,后台堆栈计数将不断增加,甚至可能导致 MemoryOutOfBound 异常。
对于问题 2:谈到您的片段标签问题,最好将标签保存在片段中。由于片段可以在任何活动中重用,而不是在每个使用它的活动中添加标签,因此如果我们将其添加到片段本身中是很好的。