Android 类似安卓backstack的instagram
简短而简单的版本:我正试图实现一个倒退,就像应用程序Instagram一样 他们的导航如何工作 在instagram中,他们使用底部栏的导航。不知道代码是什么样子的。他们创造了一种4车道的后撤 假设我点击主页(第1条车道)。然后我设法点击一篇文章->点击一个用户->点击另一篇文章->最后点击一个标签 然后,我在该车道的背面添加了4页 然后,我会做一些类似于另一条通道的事情(比如说账户页面) 我知道有两条车道,两条车道都有4页。如果我在这一点上回击按钮。我会在打开它们的时候回到原来的页面 但是如果我改为单击返回主页(从底部导航)并从那里单击backbutton。我将从1号车道返回,而不是从2号车道返回 大问题 我怎样才能像倒车一样达到这条车道?有没有一个简单的方法我没有想到 到目前为止我做了些什么 我做的不多。我创建了一个测试项目,在那里我对这种类型的导航进行了实验。到目前为止,我所做的是创建一个所有底部栏导航页面的大规模backbackbackAndroid 类似安卓backstack的instagram,android,android-navigation,Android,Android Navigation,简短而简单的版本:我正试图实现一个倒退,就像应用程序Instagram一样 他们的导航如何工作 在instagram中,他们使用底部栏的导航。不知道代码是什么样子的。他们创造了一种4车道的后撤 假设我点击主页(第1条车道)。然后我设法点击一篇文章->点击一个用户->点击另一篇文章->最后点击一个标签 然后,我在该车道的背面添加了4页 然后,我会做一些类似于另一条通道的事情(比如说账户页面) 我知道有两条车道,两条车道都有4页。如果我在这一点上回击按钮。我会在打开它们的时候回到原来的页面 但是如果
我的猜测是如何实现这类功能的,就是将后退的某些部分移到顶部,然后将另一部分移到后面。但是这怎么可能呢?我设法解决了我遇到的问题。别给我满分。我看过一个参考代码。请在下面查看 这可能不是固溶体。但它可能会帮助你理解其工作原理背后的逻辑。因此,您可以创建适合自己需要的解决方案 希望这有帮助:) 了解我的应用程序的工作原理 首先。我只是想让你们都知道我的应用程序是如何工作的。所以你知道我为什么选择我的路线来实现这个导航。我有一个活动,它保存对它正在使用的所有根片段的引用。该活动一次只添加一个根片段。取决于用户单击的按钮 当活动创建新的根片段时。它将把它推送到处理它的管理类 活动本身覆盖
onBackPressed()
并调用虚构的backbackbackbacksonBackPressed()
函数
该活动还将向管理类传递一个侦听器。此侦听器将告诉活动何时关闭应用程序。以及何时刷新当前活动片段
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();
}