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();
BackStackEntry
id和Fragment
id没有任何关系
我已经通过使用标签完成了与您所做的类似的事情。同样,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。如果您不小心创建了导航图。
对于我的应用程序,某些片段需要用户在对话框中输入 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();
BackStackEntry
id和Fragment
id没有任何关系
我已经通过使用标签完成了与您所做的类似的事情。同样,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。如果您不小心创建了导航图。