fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
@SuppressWarnings("ReferenceEquality")
    private static void addToFirstInLastOut(BackStackRecord transaction, BackStackRecord.Op op,
            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
            boolean isReorderedTransaction) {
        final Fragment fragment = op.fragment;
        if (fragment == null) {
            return; // no fragment, no transition
        }
        final int containerId = fragment.mContainerId;
        if (containerId == 0) {
            return; // no container, no transition
        }
        final int command = isPop ? INVERSE_OPS[op.cmd] : op.cmd;
        boolean setLastIn = false;
        boolean wasRemoved = false;
        boolean setFirstOut = false;
        boolean wasAdded = false;
        switch (command) {
            case BackStackRecord.OP_SHOW:
                if (isReorderedTransaction) {
                    setLastIn = fragment.mHiddenChanged && !fragment.mHidden && fragment.mAdded;
                } else {
                    setLastIn = fragment.mHidden;
                }
                wasAdded = true;
                break;
            case BackStackRecord.OP_ADD:
            case BackStackRecord.OP_ATTACH:
                if (isReorderedTransaction) {
                    setLastIn = fragment.mIsNewlyAdded;
                } else {
                    setLastIn = !fragment.mAdded && !fragment.mHidden;
                }
                wasAdded = true;
                break;
            case BackStackRecord.OP_HIDE:
                if (isReorderedTransaction) {
                    setFirstOut = fragment.mHiddenChanged && fragment.mAdded && fragment.mHidden;
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden;
                }
                wasRemoved = true;
                break;
            case BackStackRecord.OP_REMOVE:
            case BackStackRecord.OP_DETACH:
                if (isReorderedTransaction) {
                    setFirstOut = !fragment.mAdded && fragment.mView != null
                            && fragment.mView.getVisibility() == View.VISIBLE
                            && fragment.mPostponedAlpha >= 0;
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden;
                }
                wasRemoved = true;
                break;
        }
        FragmentContainerTransition containerTransition = transitioningFragments.get(containerId);
        if (setLastIn) {
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId);
            containerTransition.lastIn = fragment;
            containerTransition.lastInIsPop = isPop;
            containerTransition.lastInTransaction = transaction;
        }
        if (!isReorderedTransaction && wasAdded) {
            if (containerTransition != null && containerTransition.firstOut == fragment) {
                containerTransition.firstOut = null;
            }

            /*
             * Ensure that fragments that are entering are at least at the CREATED state
             * so that they may load Transitions using TransitionInflater.
             */
            FragmentManagerImpl manager = transaction.mManager;
            if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED
                    && !transaction.mReorderingAllowed) {
                manager.makeActive(fragment);
                manager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
            }
        }
        if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId);
            containerTransition.firstOut = fragment;
            containerTransition.firstOutIsPop = isPop;
            containerTransition.firstOutTransaction = transaction;
        }

        if (!isReorderedTransaction && wasRemoved
                && (containerTransition != null && containerTransition.lastIn == fragment)) {
            containerTransition.lastIn = null;
        }
    }
/**
     * Examines the {@code command} and may set the first out or last in fragment for the fragment's
     * container.
     *
     * @param transaction The executing transaction
     * @param op The operation being run.
     * @param transitioningFragments A structure holding the first in and last out fragments
     *                               for each fragment container.
     * @param isPop Is the operation a pop?
     * @param isReorderedTransaction True if the operations have been partially executed and the
     *                               added fragments have Views in the hierarchy or false if the
     *                               operations haven't been executed yet.
     */
Examines the  command and may set the first out or last in fragment for the fragment's
container.

@param transaction The executing transaction
@param op The operation being run.
@param transitioningFragments A structure holding the first in and last out fragments
for each fragment container.
@param isPop Is the operation a pop.
@param isReorderedTransaction True if the operations have been partially executed and the
added fragments have Views in the hierarchy or false if the
operations haven't been executed yet.
Examines the command and may set the first out or last in fragment for the fragment ' s container . @param transaction The executing transaction @param op The operation being run . @param transitioningFragments A structure holding the first in and last out fragments for each fragment container . @param isPop Is the operation a pop . @param isReorderedTransaction True if the operations have been partially executed and the added fragments have Views in the hierarchy or false if the operations haven ' t been executed yet .
@SuppressWarnings("ReferenceEquality")
    private static void addToFirstInLastOut(BackStackRecord transaction, BackStackRecord.Op op,
            SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
            boolean isReorderedTransaction) {
        final Fragment fragment = op.fragment;
        if (fragment == null) {
            return; 
        }
        final int containerId = fragment.mContainerId;
        if (containerId == 0) {
            return; 
        }
        final int command = isPop ? INVERSE_OPS[op.cmd] : op.cmd;
        boolean setLastIn = false;
        boolean wasRemoved = false;
        boolean setFirstOut = false;
        boolean wasAdded = false;
        switch (command) {
            case BackStackRecord.OP_SHOW:
                if (isReorderedTransaction) {
                    setLastIn = fragment.mHiddenChanged && !fragment.mHidden && fragment.mAdded;
                } else {
                    setLastIn = fragment.mHidden;
                }
                wasAdded = true;
                break;
            case BackStackRecord.OP_ADD:
            case BackStackRecord.OP_ATTACH:
                if (isReorderedTransaction) {
                    setLastIn = fragment.mIsNewlyAdded;
                } else {
                    setLastIn = !fragment.mAdded && !fragment.mHidden;
                }
                wasAdded = true;
                break;
            case BackStackRecord.OP_HIDE:
                if (isReorderedTransaction) {
                    setFirstOut = fragment.mHiddenChanged && fragment.mAdded && fragment.mHidden;
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden;
                }
                wasRemoved = true;
                break;
            case BackStackRecord.OP_REMOVE:
            case BackStackRecord.OP_DETACH:
                if (isReorderedTransaction) {
                    setFirstOut = !fragment.mAdded && fragment.mView != null
                            && fragment.mView.getVisibility() == View.VISIBLE
                            && fragment.mPostponedAlpha >= 0;
                } else {
                    setFirstOut = fragment.mAdded && !fragment.mHidden;
                }
                wasRemoved = true;
                break;
        }
        FragmentContainerTransition containerTransition = transitioningFragments.get(containerId);
        if (setLastIn) {
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId);
            containerTransition.lastIn = fragment;
            containerTransition.lastInIsPop = isPop;
            containerTransition.lastInTransaction = transaction;
        }
        if (!isReorderedTransaction && wasAdded) {
            if (containerTransition != null && containerTransition.firstOut == fragment) {
                containerTransition.firstOut = null;
            }
            /*
             * Ensure that fragments that are entering are at least at the CREATED state
             * so that they may load Transitions using TransitionInflater.
             */
            FragmentManagerImpl manager = transaction.mManager;
            if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED
                    && !transaction.mReorderingAllowed) {
                manager.makeActive(fragment);
                manager.moveToState(fragment, Fragment.CREATED, 0, 0, false);
            }
        }
        if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {
            containerTransition =
                    ensureContainer(containerTransition, transitioningFragments, containerId);
            containerTransition.firstOut = fragment;
            containerTransition.firstOutIsPop = isPop;
            containerTransition.firstOutTransaction = transaction;
        }
        if (!isReorderedTransaction && wasRemoved
                && (containerTransition != null && containerTransition.lastIn == fragment)) {
            containerTransition.lastIn = null;
        }
    }
@ SuppressWarnings ( "ReferenceEquality" ) private static void addToFirstInLastOut ( BackStackRecord transaction , BackStackRecord . Op op , SparseArray < FragmentContainerTransition > transitioningFragments , boolean isPop , boolean isReorderedTransaction ) { final Fragment fragment = op . fragment ; if ( fragment == null ) { return ; } final int containerId = fragment . mContainerId ; if ( containerId == 0 ) { return ; } final int command = isPop ? INVERSE_OPS [ op . cmd ] : op . cmd ; boolean setLastIn = false ; boolean wasRemoved = false ; boolean setFirstOut = false ; boolean wasAdded = false ; switch ( command ) { case BackStackRecord . OP_SHOW : if ( isReorderedTransaction ) { setLastIn = fragment . mHiddenChanged && ! fragment . mHidden && fragment . mAdded ; } else { setLastIn = fragment . mHidden ; } wasAdded = true ; break ; case BackStackRecord . OP_ADD : case BackStackRecord . OP_ATTACH : if ( isReorderedTransaction ) { setLastIn = fragment . mIsNewlyAdded ; } else { setLastIn = ! fragment . mAdded && ! fragment . mHidden ; } wasAdded = true ; break ; case BackStackRecord . OP_HIDE : if ( isReorderedTransaction ) { setFirstOut = fragment . mHiddenChanged && fragment . mAdded && fragment . mHidden ; } else { setFirstOut = fragment . mAdded && ! fragment . mHidden ; } wasRemoved = true ; break ; case BackStackRecord . OP_REMOVE : case BackStackRecord . OP_DETACH : if ( isReorderedTransaction ) { setFirstOut = ! fragment . mAdded && fragment . mView != null && fragment . mView . getVisibility ( ) == View . VISIBLE && fragment . mPostponedAlpha >= 0 ; } else { setFirstOut = fragment . mAdded && ! fragment . mHidden ; } wasRemoved = true ; break ; } FragmentContainerTransition containerTransition = transitioningFragments . get ( containerId ) ; if ( setLastIn ) { containerTransition = ensureContainer ( containerTransition , transitioningFragments , containerId ) ; containerTransition . lastIn = fragment ; containerTransition . lastInIsPop = isPop ; containerTransition . lastInTransaction = transaction ; } if ( ! isReorderedTransaction && wasAdded ) { if ( containerTransition != null && containerTransition . firstOut == fragment ) { containerTransition . firstOut = null ; } /*
             * Ensure that fragments that are entering are at least at the CREATED state
             * so that they may load Transitions using TransitionInflater.
             */ FragmentManagerImpl manager = transaction . mManager ; if ( fragment . mState < Fragment . CREATED && manager . mCurState >= Fragment . CREATED && ! transaction . mReorderingAllowed ) { manager . makeActive ( fragment ) ; manager . moveToState ( fragment , Fragment . CREATED , 0 , 0 , false ) ; } } if ( setFirstOut && ( containerTransition == null || containerTransition . firstOut == null ) ) { containerTransition = ensureContainer ( containerTransition , transitioningFragments , containerId ) ; containerTransition . firstOut = fragment ; containerTransition . firstOutIsPop = isPop ; containerTransition . firstOutTransaction = transaction ; } if ( ! isReorderedTransaction && wasRemoved && ( containerTransition != null && containerTransition . lastIn == fragment ) ) { containerTransition . lastIn = null ; } }
Examines the {@code command} and may set the first out or last in fragment for the fragment's
 container.
Examines the { @code command } and may set the first out or last in fragment for the fragment ' s container .
// no fragment, no transition // no container, no transition