Android 在不弹出的情况下查看堆栈

Android peek backstack without popping

对于我的应用程序,某些片段需要用户在对话框中输入 PIN 码才能显示。我有一个 BaseFragment class,如果需要 pin,我的所有其他片段都会扩展它存储的内容。我现在的问题是处理后退按钮,就好像用户试图返回到需要 pin 的片段,它需要首先显示 pin 对话框。

目前我正在覆盖 onBackPressed(),我想在其中查看后台堆栈以查看如果调用 popBackstack() 将恢复哪些片段,以便我可以检查是否应显示 pin 对话框。下面是我当前的代码,popFragment 返回 null:

@Override
public void onBackPressed() {
    if(getSupportFragmentManager().findFragmentById(R.id.fragment_container) instanceof BaseFragment) {
        BaseFragment frag = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container);

        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
            int index = getSupportFragmentManager().getBackStackEntryCount() - 1;
            Log.e("Back stack", Integer.toString(index));
            FragmentManager.BackStackEntry backEntry = (FragmentManager.BackStackEntry) getSupportFragmentManager().getBackStackEntryAt(index);

            BaseFragment popFragment = (BaseFragment) getSupportFragmentManager().findFragmentById(backEntry.getId());

            BaseFragment.checkAuth(this, frag, popFragment, new NavigationCallback((AppCompatActivity) this));
        } else {
            super.onBackPressed();
        }
    } else {
        super.onBackPressed();
    }
}

我已经检查过 backEntry 是否为 null 而不是。 backEntry.getId() 也返回值为 1,所以我不确定为什么 findFragmentById() 然后为空。我也不认为这与我如何显示片段有关,但这里也是我的代码:

FragmentManager fragManager = mActivity.getSupportFragmentManager();
FragmentTransaction transaction = fragManager.beginTransaction();
transaction.replace(R.id.fragment_container, mFragment);
transaction.addToBackStack(null);
transaction.commit();

BackStackEntryid和Fragmentid没有任何关系

我已经通过使用标签完成了与您所做的类似的事情。同样,BackStackEntry 标签和 Fragment 标签彼此无关;但是,通过为两个标签使用相同的值,您可以实现您的目标。

String tag = ...
FragmentManager fragManager = mActivity.getSupportFragmentManager();
FragmentTransaction transaction = fragManager.beginTransaction();
// tag is associated with fragment
transaction.replace(R.id.fragment_container, mFragment, tag);
// same tag is associated with back stack entry
transaction.addToBackStack(tag);
transaction.commit();

...

int count = fragmentManager.getBackStackEntryCount();
if (count > 0) {
    FragmentManager.BackStackEntry topBackStackEntry = 
            fragmentManager.getBackStackEntryAt(count - 1);
    String tag = topBackStackEntry.getName();

    if (tag != null) {
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment != null) {
            // we found the fragment
            // you can also sanity-check here with fragment.isResumed()
        }
    }
}

你离开了 Frag-A -> Frag-B -> Frag-C。现在您想返回 Frag-A 而不为 Frag-A 创建新的 Fragment 视图? 这是解决方案:

Navigation.findNavController(requireView()).popBackStack(R.id.Frag_A, false)

同时删除您的导航条目 action_Frag_C_to_Frag_A。如果您不小心创建了导航图。