Android 类似安卓backstack的instagram

Android 类似安卓backstack的instagram,android,android-navigation,Android,Android Navigation,简短而简单的版本:我正试图实现一个倒退,就像应用程序Instagram一样 他们的导航如何工作 在instagram中,他们使用底部栏的导航。不知道代码是什么样子的。他们创造了一种4车道的后撤 假设我点击主页(第1条车道)。然后我设法点击一篇文章->点击一个用户->点击另一篇文章->最后点击一个标签 然后,我在该车道的背面添加了4页 然后,我会做一些类似于另一条通道的事情(比如说账户页面) 我知道有两条车道,两条车道都有4页。如果我在这一点上回击按钮。我会在打开它们的时候回到原来的页面 但是如果

简短而简单的版本:我正试图实现一个倒退,就像应用程序Instagram一样

他们的导航如何工作

在instagram中,他们使用底部栏的导航。不知道代码是什么样子的。他们创造了一种4车道的后撤

假设我点击主页(第1条车道)。然后我设法点击一篇文章->点击一个用户->点击另一篇文章->最后点击一个标签

然后,我在该车道的背面添加了4页

然后,我会做一些类似于另一条通道的事情(比如说账户页面)

我知道有两条车道,两条车道都有4页。如果我在这一点上回击按钮。我会在打开它们的时候回到原来的页面

但是如果我改为单击返回主页(从底部导航)并从那里单击backbutton。我将从1号车道返回,而不是从2号车道返回

大问题

我怎样才能像倒车一样达到这条车道?有没有一个简单的方法我没有想到

到目前为止我做了些什么

我做的不多。我创建了一个测试项目,在那里我对这种类型的导航进行了实验。到目前为止,我所做的是创建一个所有底部栏导航页面的大规模backbackback


我的猜测是如何实现这类功能的,就是将后退的某些部分移到顶部,然后将另一部分移到后面。但是这怎么可能呢?

我设法解决了我遇到的问题。别给我满分。我看过一个参考代码。请在下面查看

这可能不是固溶体。但它可能会帮助你理解其工作原理背后的逻辑。因此,您可以创建适合自己需要的解决方案

希望这有帮助:)

了解我的应用程序的工作原理

首先。我只是想让你们都知道我的应用程序是如何工作的。所以你知道我为什么选择我的路线来实现这个导航。我有一个活动,它保存对它正在使用的所有根片段的引用。该活动一次只添加一个根片段。取决于用户单击的按钮

当活动创建新的根片段时。它将把它推送到处理它的管理类

活动本身覆盖
onBackPressed()
并调用虚构的backbackbackbacks
onBackPressed()
函数

该活动还将向管理类传递一个侦听器。此侦听器将告诉活动何时关闭应用程序。以及何时刷新当前活动片段

BackStackManager.java

这是管理课。它保留了对所有不同backbackback的引用。它还将任何片段事务职责委托给它的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
}
BackStack.java

这是一个简单的类,它只处理对根的内部引用和对所有backstack子条目的标记。以及这些子条目的处理

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
}
参考资料


我在手机上,所以现在无法回答,但您可以在每个页面中使用FragmentManager及其自己的back stack,并覆盖主活动的onBackPressed以调用活动FragmentManager的popBackStack方法
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();

}