diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java index a0f53df0..ed8019b1 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java @@ -95,6 +95,7 @@ public abstract class QMUIFragment extends Fragment implements FragmentSchemeRefreshable{ static final String SWIPE_BACK_VIEW = "swipe_back_view"; private static final String TAG = QMUIFragment.class.getSimpleName(); + private static final String QMUI_IS_MUTI_STARTED_KEY = "qmui_is_muti_started"; public static final TransitionConfig SLIDE_TRANSITION_CONFIG = new TransitionConfig( R.animator.slide_in_right, R.animator.slide_out_left, @@ -135,6 +136,7 @@ public abstract class QMUIFragment extends Fragment implements private boolean mIsInSwipeBack = false; private boolean mFinishActivityIfOnBackPressed = false; + boolean mIsMutiStarted = false; private int mEnterAnimationStatus = ANIMATION_ENTER_STATUS_NOT_START; private MutableLiveData isInEnterAnimationLiveData = new MutableLiveData<>(false); @@ -207,6 +209,12 @@ public abstract class QMUIFragment extends Fragment implements return !isRemoving() && mBaseView != null; } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(QMUI_IS_MUTI_STARTED_KEY, mIsMutiStarted); + } + @Override public void onDestroyView() { super.onDestroyView(); @@ -419,6 +427,49 @@ public abstract class QMUIFragment extends Fragment implements return startFragment(fragment, provider); } + + public int startFragment(QMUIFragment... fragments){ + if (!checkStateLoss("startFragment")) { + return -1; + } + if(fragments.length == 0){ + return -1; + } + QMUIFragmentContainerProvider provider = findFragmentContainerProvider(true); + if (provider == null) { + if (BuildConfig.DEBUG) { + throw new RuntimeException("Can not find the fragment container provider."); + } else { + Log.d(TAG, "Can not find the fragment container provider."); + return -1; + } + } + if(provider.getContainerFragmentManager().isDestroyed()){ + return -1; + } + if(fragments.length == 1){ + return startFragment(fragments[0], provider); + } + ArrayList transactions = new ArrayList<>(); + for (QMUIFragment fragment : fragments) { + FragmentTransaction transaction = provider.getContainerFragmentManager() + .beginTransaction() + .setPrimaryNavigationFragment(null); + TransitionConfig transitionConfig = fragments[0].onFetchTransitionConfig(); + fragment.mIsMutiStarted = true; + String tagName = fragment.getClass().getSimpleName(); + transaction.setCustomAnimations(transitionConfig.enter, transitionConfig.exit, transitionConfig.popenter, transitionConfig.popout); + transaction.replace(provider.getContextViewId(), fragment, tagName); + transaction.addToBackStack(tagName); + transactions.add(transaction); + transaction.setReorderingAllowed(true); + } + for(FragmentTransaction transaction: transactions){ + transaction.commit(); + } + return 0; + } + /** * simulate the behavior of startActivityForResult/onActivityResult: * 1. Jump fragment1 to fragment2 via startActivityForResult(fragment2, requestCode) @@ -484,6 +535,14 @@ public abstract class QMUIFragment extends Fragment implements notifyEffect(new FragmentResultEffect(mTargetFragmentUUid, resultCode, mTargetRequestCode, data)); } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(savedInstanceState != null){ + mIsMutiStarted = savedInstanceState.getBoolean(QMUI_IS_MUTI_STARTED_KEY, false); + } + } + @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -519,6 +578,9 @@ public abstract class QMUIFragment extends Fragment implements public int getDragDirection(SwipeBackLayout swipeBackLayout, SwipeBackLayout.ViewMoveAction viewMoveAction, float downX, float downY, float dx, float dy, float touchSlop) { mCalled = false; + if(mIsMutiStarted){ + return DRAG_DIRECTION_NONE; + } boolean canHandle = canHandleSwipeBack(); if (canHandle && !mCalled) { throw new RuntimeException(getClass().getSimpleName() + " did not call through to super.shouldPreventSwipeBack()"); diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragmentActivity.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragmentActivity.java index de7f21f3..b2b82e6b 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragmentActivity.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragmentActivity.java @@ -39,6 +39,8 @@ import com.qmuiteam.qmui.arch.first.FirstFragmentFinder; import com.qmuiteam.qmui.arch.first.FirstFragmentFinders; import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import java.util.ArrayList; + /** * the container activity for {@link QMUIFragment}. * Created by cgspine on 15/9/14. @@ -116,10 +118,55 @@ public abstract class QMUIFragmentActivity extends InnerBaseActivity implements mIsFirstFragmentAdded = true; } } + if(!mIsFirstFragmentAdded){ + mIsFirstFragmentAdded = instantiationMutiFragment(intent); + } Log.i(TAG, "the time it takes to inject first fragment from annotation is " + (System.currentTimeMillis() - start)); } } + protected boolean instantiationMutiFragment(Intent intent){ + return false; + } + + protected boolean initMutiFragment(QMUIFragment... fragments){ + if(fragments.length == 0){ + return false; + } + if(fragments.length == 1){ + QMUIFragment fragment = fragments[0]; + String tagName = fragment.getClass().getSimpleName(); + getSupportFragmentManager() + .beginTransaction() + .add(getContextViewId(), fragment, tagName) + .addToBackStack(tagName) + .commit(); + return true; + } + ArrayList transactions = new ArrayList<>(); + FragmentManager fragmentManager = getSupportFragmentManager(); + for (int i=0; i