我設法解決了我遇到的問題。不要給我充分的信用。我有一個我看過的參考代碼。請檢查下面。
這可能不是一個可靠的解決方案。但它可以幫助你理解它的工作原理。因此,您可以創建適合您需求的解決方案。
希望這有助於:)
背景我的應用程序是如何工作的
開始。我只想讓大家知道我的應用程序的工作原理。所以你知道我爲什麼選擇了實現這種導航的路線。我有一個活動,它保留對所使用的所有根片段的引用。該活動一次僅添加一個根片段。取決於用戶點擊的按鈕。
活動創建新的根片段時。它會將其推送到處理它的管理類。
該活動本身覆蓋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方法 –