BackStack 没有导航到正确的 Fragment

Posted

技术标签:

【中文标题】BackStack 没有导航到正确的 Fragment【英文标题】:BackStack not navigating to the correct Fragment 【发布时间】:2021-09-29 10:42:23 【问题描述】:

您好,我正在尝试使用 addToBaackStack 在一些片段之间导航,但遇到了问题, 好的,我会详细解释,所以不要混淆

1 :- 我只有一个活动(主活动),它包含所有其他片段和一个片段容器来保存其中的片段,我已经在主活动中实现了底部导航,底部导航有 5 个主要片段主页、关注、上传、通知和个人资料我的问题与个人资料片段有关

2 :- 在配置文件片段中,我有一些按钮,例如编辑配置文件按钮,它打开编辑配置文件片段,但现在当我按下它时,它应该导航回它没有执行的配置文件片段,它正在导航到底部导航的最后一个片段(可以是任何其他主要片段,例如,如果我的最后一个片段在片段之后,那么当我从编辑配置文件片段返回时,它会转到下一个片段)但这不会发生如果我在编辑配置文件片段中放置一个后退箭头图标,那么当我单击后退箭头时,它会完美地将我导航到配置文件片段,因为它与 addToBackStack 无关

这表明问题与我的底部导航有关,但我不知道如何准确修复它

Prifile_Fragment.java

editProfileButton.setOnClickListener(v -> 
            Fragment edit_profile = new Edit_Profile();
            assert getFragmentManager() != null;
            FragmentTransaction transaction = getFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_container, edit_profile);
            transaction.addToBackStack(null);
            transaction.commit();
        );

MainActivity.java // 实现底部导航的地方

public class MainActivity extends AppCompatActivity 

    public BottomNavigationView bottomNavigationView;
    Deque<Integer> integerDeque = new ArrayDeque<>(4);
    boolean flag = true;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        setContentView(R.layout.activity_main);
        Window window = this.getWindow();
        window.setStatusBarColor(this.getResources().getColor(R.color.black));
        bottomNavigationView = findViewById(R.id.bottom_navigation_view);
        integerDeque.push(R.id.nav_home);
        loadFragments(new Home_Fragment());
        bottomNavigationView.setSelectedItemId(R.id.nav_home);

        bottomNavigationView.setOnNavigationItemSelectedListener(
                item -> 
                    int id = item.getItemId();
                    if (integerDeque.contains(id)) 
                        if (id == R.id.nav_home) 
                            integerDeque.size();
                            if (flag) 
                                integerDeque.addFirst(R.id.nav_home);
                                flag = false;
                            
                        
                        integerDeque.remove(id);
                    
                    integerDeque.push(id);
                    loadFragments(getFragment(item.getItemId()));
                    return false;
                
        );

    

    @SuppressLint("NonConstantResourceId")
    private Fragment getFragment(int itemId) 
        switch (itemId) 
            case R.id.nav_home:
                bottomNavigationView.getMenu().getItem(0).setChecked(true);
                return new Home_Fragment();
            case R.id.nav_following:
                bottomNavigationView.getMenu().getItem(1).setChecked(true);
                return new Following_Fragment();
            case R.id.nav_upload:
                bottomNavigationView.getMenu().getItem(2).setChecked(true);
                return new Upload_Fragment();
            case R.id.nav_notification:
                bottomNavigationView.getMenu().getItem(3).setChecked(true);
                return new Notification_Fragment();
            case R.id.nav_profile:
                bottomNavigationView.getMenu().getItem(4).setChecked(true);
                return new Profile_Fragment();
        
        bottomNavigationView.getMenu().getItem(0).setChecked(true);
        return new Home_Fragment();
    

    public void loadFragments(Fragment fragment) 
        if (fragment != null) 
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
                    .commit();
        
    

    @Override
    public void onBackPressed() 
        integerDeque.pop();
        if (!integerDeque.isEmpty()) 
            loadFragments(getFragment(integerDeque.peek()));
         else 
            finish();
        
    

【问题讨论】:

【参考方案1】:

您考虑过使用popBackStack 吗?你可以试试这个。

@Override
public void onBackPressed() 
    final FragmentManager fragmentManager = getSupportFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 0) 
        fragmentManager.popBackStack();
     else 
        finish();
    

【讨论】:

是的,它有效,但有一个小问题我希望它也导航到底部导航中的最后一个片段并在主页片段后退出

以上是关于BackStack 没有导航到正确的 Fragment的主要内容,如果未能解决你的问题,请参考以下文章

如何将 android 导航 backstack 弹出到某个片段?

导航到 Jetpack Navigation 中的另一个 Fragment 后将 DialogFragment 保留在 backstack 中

具有多个 backstack 的片段

当backstack为空时,按下android上的后退按钮会破坏导航逻辑

使用单独的 backstack 创建类似底部导航的 Instagram

导航抽屉backstack,如何让actionbar标题在点击后随片段改变