Search in sources :

Example 1 with SimpleSwapChangeHandler

use of com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler in project Conductor by bluelinelabs.

the class Router method rebindIfNeeded.

/**
 * Attaches this Router's existing backstack to its container if one exists.
 */
@UiThread
public void rebindIfNeeded() {
    ThreadUtils.ensureMainThread();
    Iterator<RouterTransaction> backstackIterator = backstack.reverseIterator();
    while (backstackIterator.hasNext()) {
        RouterTransaction transaction = backstackIterator.next();
        if (transaction.controller.getNeedsAttach()) {
            performControllerChange(transaction, null, true, new SimpleSwapChangeHandler(false));
        }
    }
}
Also used : SimpleSwapChangeHandler(com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler) UiThread(android.support.annotation.UiThread)

Example 2 with SimpleSwapChangeHandler

use of com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler in project Conductor by bluelinelabs.

the class Router method setBackstack.

/**
 * Sets the backstack, transitioning from the current top controller to the top of the new stack (if different)
 * using the passed {@link ControllerChangeHandler}
 *
 * @param newBackstack  The new backstack
 * @param changeHandler An optional change handler to be used to handle the root view of transition
 */
@SuppressWarnings("WeakerAccess")
@UiThread
public void setBackstack(@NonNull List<RouterTransaction> newBackstack, @Nullable ControllerChangeHandler changeHandler) {
    ThreadUtils.ensureMainThread();
    List<RouterTransaction> oldTransactions = getBackstack();
    List<RouterTransaction> oldVisibleTransactions = getVisibleTransactions(backstack.iterator());
    removeAllExceptVisibleAndUnowned();
    ensureOrderedTransactionIndices(newBackstack);
    ensureNoDuplicateControllers(newBackstack);
    backstack.setBackstack(newBackstack);
    List<RouterTransaction> transactionsToBeRemoved = new ArrayList<>();
    for (RouterTransaction oldTransaction : oldTransactions) {
        boolean contains = false;
        for (RouterTransaction newTransaction : newBackstack) {
            if (oldTransaction.controller == newTransaction.controller) {
                contains = true;
                break;
            }
        }
        if (!contains) {
            // Inform the controller that it will be destroyed soon
            oldTransaction.controller.isBeingDestroyed = true;
            transactionsToBeRemoved.add(oldTransaction);
        }
    }
    // Ensure all new controllers have a valid router set
    Iterator<RouterTransaction> backstackIterator = backstack.reverseIterator();
    while (backstackIterator.hasNext()) {
        RouterTransaction transaction = backstackIterator.next();
        transaction.onAttachedToRouter();
        setControllerRouter(transaction.controller);
    }
    if (newBackstack.size() > 0) {
        List<RouterTransaction> reverseNewBackstack = new ArrayList<>(newBackstack);
        Collections.reverse(reverseNewBackstack);
        List<RouterTransaction> newVisibleTransactions = getVisibleTransactions(reverseNewBackstack.iterator());
        boolean newRootRequiresPush = !(newVisibleTransactions.size() > 0 && oldTransactions.contains(newVisibleTransactions.get(0)));
        boolean visibleTransactionsChanged = !backstacksAreEqual(newVisibleTransactions, oldVisibleTransactions);
        if (visibleTransactionsChanged) {
            RouterTransaction oldRootTransaction = oldVisibleTransactions.size() > 0 ? oldVisibleTransactions.get(0) : null;
            RouterTransaction newRootTransaction = newVisibleTransactions.get(0);
            // Replace the old root with the new one
            if (oldRootTransaction == null || oldRootTransaction.controller != newRootTransaction.controller) {
                // Ensure the existing root controller is fully pushed to the view hierarchy
                if (oldRootTransaction != null) {
                    ControllerChangeHandler.completeHandlerImmediately(oldRootTransaction.controller.getInstanceId());
                }
                performControllerChange(newRootTransaction, oldRootTransaction, newRootRequiresPush, changeHandler);
            }
            // Remove all visible controllers that were previously on the backstack
            for (int i = oldVisibleTransactions.size() - 1; i > 0; i--) {
                RouterTransaction transaction = oldVisibleTransactions.get(i);
                if (!newVisibleTransactions.contains(transaction)) {
                    ControllerChangeHandler localHandler = changeHandler != null ? changeHandler.copy() : new SimpleSwapChangeHandler();
                    localHandler.setForceRemoveViewOnPush(true);
                    ControllerChangeHandler.completeHandlerImmediately(transaction.controller.getInstanceId());
                    performControllerChange(null, transaction, newRootRequiresPush, localHandler);
                }
            }
            // Add any new controllers to the backstack
            for (int i = 1; i < newVisibleTransactions.size(); i++) {
                RouterTransaction transaction = newVisibleTransactions.get(i);
                if (!oldVisibleTransactions.contains(transaction)) {
                    performControllerChange(transaction, newVisibleTransactions.get(i - 1), true, transaction.pushChangeHandler());
                }
            }
        }
    } else {
        // Remove all visible controllers that were previously on the backstack
        for (int i = oldVisibleTransactions.size() - 1; i >= 0; i--) {
            RouterTransaction transaction = oldVisibleTransactions.get(i);
            ControllerChangeHandler localHandler = changeHandler != null ? changeHandler.copy() : new SimpleSwapChangeHandler();
            ControllerChangeHandler.completeHandlerImmediately(transaction.controller.getInstanceId());
            performControllerChange(null, transaction, false, localHandler);
        }
    }
    // change handler runs.
    for (RouterTransaction removedTransaction : transactionsToBeRemoved) {
        removedTransaction.controller.destroy();
    }
}
Also used : NoOpControllerChangeHandler(com.bluelinelabs.conductor.internal.NoOpControllerChangeHandler) ArrayList(java.util.ArrayList) SimpleSwapChangeHandler(com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler) UiThread(android.support.annotation.UiThread)

Example 3 with SimpleSwapChangeHandler

use of com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler in project Conductor by bluelinelabs.

the class ControllerChangeHandler method executeChange.

private static void executeChange(@Nullable final Controller to, @Nullable final Controller from, final boolean isPush, @Nullable final ViewGroup container, @Nullable final ControllerChangeHandler inHandler, @NonNull final List<ControllerChangeListener> listeners) {
    if (container != null) {
        final ControllerChangeHandler handler;
        if (inHandler == null) {
            handler = new SimpleSwapChangeHandler();
        } else if (inHandler.hasBeenUsed && !inHandler.isReusable()) {
            handler = inHandler.copy();
        } else {
            handler = inHandler;
        }
        handler.hasBeenUsed = true;
        if (from != null) {
            if (isPush) {
                completeHandlerImmediately(from.getInstanceId());
            } else {
                abortOrComplete(from, to, handler);
            }
        }
        if (to != null) {
            inProgressChangeHandlers.put(to.getInstanceId(), new ChangeHandlerData(handler, isPush));
        }
        for (ControllerChangeListener listener : listeners) {
            listener.onChangeStarted(to, from, isPush, container, handler);
        }
        final ControllerChangeType toChangeType = isPush ? ControllerChangeType.PUSH_ENTER : ControllerChangeType.POP_ENTER;
        final ControllerChangeType fromChangeType = isPush ? ControllerChangeType.PUSH_EXIT : ControllerChangeType.POP_EXIT;
        final View toView;
        if (to != null) {
            toView = to.inflate(container);
            to.changeStarted(handler, toChangeType);
        } else {
            toView = null;
        }
        final View fromView;
        if (from != null) {
            fromView = from.getView();
            from.changeStarted(handler, fromChangeType);
        } else {
            fromView = null;
        }
        handler.performChange(container, fromView, toView, isPush, new ControllerChangeCompletedListener() {

            @Override
            public void onChangeCompleted() {
                if (from != null) {
                    from.changeEnded(handler, fromChangeType);
                }
                if (to != null) {
                    inProgressChangeHandlers.remove(to.getInstanceId());
                    to.changeEnded(handler, toChangeType);
                }
                for (ControllerChangeListener listener : listeners) {
                    listener.onChangeCompleted(to, from, isPush, container, handler);
                }
                if (handler.forceRemoveViewOnPush && fromView != null) {
                    ViewParent fromParent = fromView.getParent();
                    if (fromParent != null && fromParent instanceof ViewGroup) {
                        ((ViewGroup) fromParent).removeView(fromView);
                    }
                }
                if (handler.removesFromViewOnPush() && from != null) {
                    from.setNeedsAttach(false);
                }
            }
        });
    }
}
Also used : ViewParent(android.view.ViewParent) ViewGroup(android.view.ViewGroup) SimpleSwapChangeHandler(com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler) View(android.view.View)

Example 4 with SimpleSwapChangeHandler

use of com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler in project Conductor by bluelinelabs.

the class ControllerLifecycleCallbacksTests method testChildLifecycleOrderingAfterUnexpectedAttach.

@Test
public void testChildLifecycleOrderingAfterUnexpectedAttach() {
    Controller parent = new TestController();
    parent.setRetainViewMode(RetainViewMode.RETAIN_DETACH);
    router.pushController(RouterTransaction.with(parent).pushChangeHandler(MockChangeHandler.defaultHandler()).popChangeHandler(MockChangeHandler.defaultHandler()));
    TestController child = new TestController();
    child.setRetainViewMode(RetainViewMode.RETAIN_DETACH);
    Router childRouter = parent.getChildRouter((ViewGroup) parent.getView().findViewById(TestController.VIEW_ID));
    childRouter.setRoot(RouterTransaction.with(child).pushChangeHandler(new SimpleSwapChangeHandler()).popChangeHandler(new SimpleSwapChangeHandler()));
    assertTrue(parent.isAttached());
    assertTrue(child.isAttached());
    ViewUtils.reportAttached(parent.getView(), false, true);
    assertFalse(parent.isAttached());
    assertFalse(child.isAttached());
    ViewUtils.reportAttached(child.getView(), true);
    assertFalse(parent.isAttached());
    assertFalse(child.isAttached());
    ViewUtils.reportAttached(parent.getView(), true);
    assertTrue(parent.isAttached());
    assertTrue(child.isAttached());
}
Also used : TestController(com.bluelinelabs.conductor.util.TestController) TestController(com.bluelinelabs.conductor.util.TestController) SimpleSwapChangeHandler(com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler) Test(org.junit.Test)

Example 5 with SimpleSwapChangeHandler

use of com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler in project Conductor by bluelinelabs.

the class Router method destroy.

void destroy(boolean popViews) {
    popsLastView = true;
    final List<RouterTransaction> poppedControllers = backstack.popAll();
    trackDestroyingControllers(poppedControllers);
    if (popViews && poppedControllers.size() > 0) {
        RouterTransaction topTransaction = poppedControllers.get(0);
        topTransaction.controller().addLifecycleListener(new LifecycleListener() {

            @Override
            public void onChangeEnd(@NonNull Controller controller, @NonNull ControllerChangeHandler changeHandler, @NonNull ControllerChangeType changeType) {
                if (changeType == ControllerChangeType.POP_EXIT) {
                    for (int i = poppedControllers.size() - 1; i > 0; i--) {
                        RouterTransaction transaction = poppedControllers.get(i);
                        performControllerChange(null, transaction, true, new SimpleSwapChangeHandler());
                    }
                }
            }
        });
        performControllerChange(null, topTransaction, false, topTransaction.popChangeHandler());
    }
}
Also used : NoOpControllerChangeHandler(com.bluelinelabs.conductor.internal.NoOpControllerChangeHandler) LifecycleListener(com.bluelinelabs.conductor.Controller.LifecycleListener) SimpleSwapChangeHandler(com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler)

Aggregations

SimpleSwapChangeHandler (com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler)5 UiThread (android.support.annotation.UiThread)2 NoOpControllerChangeHandler (com.bluelinelabs.conductor.internal.NoOpControllerChangeHandler)2 View (android.view.View)1 ViewGroup (android.view.ViewGroup)1 ViewParent (android.view.ViewParent)1 LifecycleListener (com.bluelinelabs.conductor.Controller.LifecycleListener)1 TestController (com.bluelinelabs.conductor.util.TestController)1 ArrayList (java.util.ArrayList)1 Test (org.junit.Test)1