简单而简短的版本:我正试图实现一个像Instagram应用程序一样的后台程序。
他们的导航是如何工作的
在instagram中,他们使用来自底部栏的导航。而不知道代码是什么样子。他们创造了某种4车道的背靠背。
所以,让我们说,我点击家(第一车道)。然后,我设法点击一个帖子->,点击一个用户->,点击另一个帖子->,最后点击一个哈希标签
然后,我在那条车道的后排增加了4页。
然后,我做一些类似于另一条车道的事情(比如帐户页面)。
我知道两条车道都有4页。如果我现在按下按钮的话。当我打开它们的时候,我会回到原来的页面。
但是,如果我单击“返回到家”(从底部导航)并从那里单击“回退”按钮的话。我会从1号车道返回,而不是2号车道。
大问题
我怎么才能像背靠背那样实现这条车道呢?有没有一种简单的方法让我不去想?
到目前为止我所做的一切,
我做得不多。我创建了一个测试项目,在那里我尝试了这种类型的导航。到目前为止,我所做的就是为我所有的底部导航页面创建一个庞大的背靠背。
我对如何实现这种功能的猜测是,将背靠背的某些部分移到顶部,将另一部分移回。但这怎么可能?
发布于 2017-07-22 11:38:50
我设法解决了我正在处理的问题。不要给我充分的信任。我看过一个参考代码。请检查下面。
这也许不是一个固溶体。但是它可以帮助你理解它是如何工作的逻辑。因此,您可以创建适合您需要的自己的解决方案。
希望这会有所帮助:)
背景我的应用程序是如何工作的
首先。我只想让大家知道我的应用程序是如何工作的。所以你知道我为什么选择实现这个导航的路线。我有一个活动,它保存对它正在使用的所有根片段的引用。该活动一次只添加一个根片段。取决于用户单击的按钮。
当活动创建一个新的根片段时。它将把它推送给处理它的管理类。
该活动本身覆盖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
https://stackoverflow.com/questions/45176274
复制相似问题