我设法解决了我遇到的问题。不要给我充分的信用。我有一个我看过的参考代码。请检查下面。
这可能不是一个可靠的解决方案。但它可以帮助你理解它的工作原理。因此,您可以创建适合您需求的解决方案。
希望这有助于:)
背景我的应用程序是如何工作的
开始。我只想让大家知道我的应用程序的工作原理。所以你知道我为什么选择了实现这种导航的路线。我有一个活动,它保留对所使用的所有根片段的引用。该活动一次仅添加一个根片段。取决于用户点击的按钮。
活动创建新的根片段时。它会将其推送到处理它的管理类。
该活动本身覆盖onBackPressed()
,并调用构成的backstacks onBackpressed()
函数。
该活动还会将监听者传递给管理类。这个监听器会告诉活动什么时候关闭应用程序。并且当刷新当前活性片段
BackStackManager.java
这是管理类。它保持对所有不同的后台的参考。它还将任何片段事务责任委托给其FragmentManager类。
public class BackStackManager {
//region Members
/** Reference to the made up backstack */
private final LinkedList<BackStack> mBackStacks;
/** Reference to listener */
private final BackStackHelperListener mListener;
/** Reference to internal fragment manager */
private final BackStackFragmentManager mFragmentManager;
//endregion
//region Constructors
public BackStackManager(@NonNull final BackStackHelperListener listener,
@NonNull final FragmentManager fragmentManager) {
mBackStacks = new LinkedList<>();
mListener = listener;
mFragmentManager = new BackStackFragmentManager(fragmentManager);
}
//endregion
//region Methods
/** When adding a new root fragment
* IMPORTANT: Activity his holding the reference to the root. */
public void addRootFragment(@NonNull final Fragment fragment,
final int layoutId) {
if (!isAdded(fragment)) {
addRoot(fragment, layoutId);
}
else if (isAdded(fragment) && isCurrent(fragment)) {
refreshCurrentRoot();
}
else {
switchRoot(fragment);
mFragmentManager.switchFragment(fragment);
}
}
/** When activity is calling onBackPressed */
public void onBackPressed() {
final BackStack current = mBackStacks.peekLast();
final String uuid = current.pop();
if (uuid == null) {
removeRoot(current);
}
else {
mFragmentManager.popBackStack(uuid);
}
}
/** Adding child fragment */
public void addChildFragment(@NonNull final Fragment fragment,
final int layoutId) {
final String uuid = UUID.randomUUID().toString();
final BackStack backStack = mBackStacks.peekLast();
backStack.push(uuid);
mFragmentManager.addChildFragment(fragment, layoutId, uuid);
}
/** Remove root */
private void removeRoot(@NonNull final BackStack backStack) {
mBackStacks.remove(backStack);
//After removing. Call close app listener if the backstack is empty
if (mBackStacks.isEmpty()) {
mListener.closeApp();
}
//Change root since the old one is out
else {
BackStack newRoot = mBackStacks.peekLast();
mFragmentManager.switchFragment(newRoot.mRootFragment);
}
}
/** Adding root fragment */
private void addRoot(@NonNull final Fragment fragment, final int layoutId) {
mFragmentManager.addFragment(fragment, layoutId);
//Create a new backstack and add it to the list
final BackStack backStack = new BackStack(fragment);
mBackStacks.offerLast(backStack);
}
/** Switch root internally in the made up backstack */
private void switchRoot(@NonNull final Fragment fragment) {
for (int i = 0; i < mBackStacks.size(); i++) {
BackStack backStack = mBackStacks.get(i);
if (backStack.mRootFragment == fragment) {
mBackStacks.remove(i);
mBackStacks.offerLast(backStack);
break;
}
}
}
/** Let listener know to call refresh */
private void refreshCurrentRoot() {
mListener.refresh();
}
/** Convenience method */
private boolean isAdded(@NonNull final Fragment fragment) {
for (BackStack backStack : mBackStacks) {
if (backStack.mRootFragment == fragment) {
return true;
}
}
return false;
}
/** Convenience method */
private boolean isCurrent(@NonNull final Fragment fragment) {
final BackStack backStack = mBackStacks.peekLast();
return backStack.mRootFragment == fragment;
}
//endregion
}
BackStackFragmentManager.java
该类处理所有片段的交易。如添加/删除/隐藏/显示。该类位于BackStackManager类中。
public class BackStackFragmentManager {
//region Members
/** Reference to fragment manager */
private final FragmentManager mFragmentManager;
/** Last added fragment */
private Fragment mLastAdded;
//endregion
//region Constructors
public BackStackFragmentManager(@NonNull final FragmentManager fragmentManager) {
mFragmentManager = fragmentManager;
}
//endregion
//region Methods
/** Switch root fragment */
public void switchFragment(@NonNull final Fragment fragment) {
final FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.show(fragment);
transaction.hide(mLastAdded);
transaction.commit();
mLastAdded = fragment;
}
/** Adding child fragment to a root */
public void addChildFragment(@NonNull final Fragment fragment,
final int layoutId,
@NonNull final String tag) {
final FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.add(layoutId, fragment, tag);
transaction.commit();
}
/** Add a root fragment */
public void addFragment(@NonNull Fragment fragment, int layoutId) {
final FragmentTransaction transaction = mFragmentManager.beginTransaction();
//since we hide/show. This should only happen initially
if (!fragment.isAdded()) {
transaction.add(layoutId, fragment, fragment.getClass().getName());
}
else {
transaction.show(fragment);
}
if (mLastAdded != null) {
transaction.hide(mLastAdded);
}
transaction.commit();
mLastAdded = fragment;
}
/** Pop back stack
* Function is removing childs that is not used!
*/
public void popBackStack(@NonNull final String tag) {
final Fragment fragment = mFragmentManager.findFragmentByTag(tag);
final FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
//endregion
}
BackStack.java
这是一个简单的类,只是处理的根和标签的所有返回堆栈子条目内引用。而且处理这些子项的
public class BackStack {
//region Members
public final Fragment mRootFragment;
final LinkedList<String> mStackItems;
//endregion
//region Constructors
public BackStack(@NonNull final Fragment rootFragment) {
mRootFragment = rootFragment;
mStackItems = new LinkedList<>();
}
//endregion
//region Methods
public String pop() {
if (isEmpty()) return null;
return mStackItems.pop();
}
public void push(@NonNull final String id) {
mStackItems.push(id);
}
public boolean isEmpty() {
return mStackItems.isEmpty();
}
//endregion
}
监听
不多说了这件事。它是由活动实现
public interface BackStackHelperListener {
/** Let the listener know that the app should close. The backstack is depleted */
void closeApp();
/** Let the listener know that the user clicked on an already main root. So app can do
* a secondary action if needed
*/
void refresh();
}
参考
https://blog.f22labs.com/instagram-like-bottom-tab-fragment-transaction-android-389976fb8759
我在移动所以现在不能回答,但你可以在每个国家都有它自己的页面使用FragmentManager回堆栈并覆盖主活动的onBackPressed来调用活动的FragmentManager的popBackStack方法 –