|
|
@@ -1,144 +0,0 @@
|
|
|
-package com.example.modifier;
|
|
|
-
|
|
|
-import android.content.Context;
|
|
|
-import android.os.Bundle;
|
|
|
-import android.util.Log;
|
|
|
-import android.view.View;
|
|
|
-
|
|
|
-import androidx.annotation.IdRes;
|
|
|
-import androidx.annotation.NonNull;
|
|
|
-import androidx.annotation.Nullable;
|
|
|
-import androidx.fragment.app.Fragment;
|
|
|
-import androidx.fragment.app.FragmentManager;
|
|
|
-import androidx.fragment.app.FragmentTransaction;
|
|
|
-import androidx.navigation.NavDestination;
|
|
|
-import androidx.navigation.NavOptions;
|
|
|
-import androidx.navigation.Navigator;
|
|
|
-import androidx.navigation.fragment.FragmentNavigator;
|
|
|
-
|
|
|
-import java.lang.reflect.Field;
|
|
|
-import java.util.ArrayDeque;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-@Navigator.Name("fixFragment")
|
|
|
-public class FixFragmentNavigator extends FragmentNavigator {
|
|
|
- private final String TAG = "ReLoadFragmentNavictor";
|
|
|
- private final Context mContext;
|
|
|
- private final FragmentManager mFragmentManager;
|
|
|
- private final int mContainerId;
|
|
|
- String oldClassName = null;
|
|
|
-
|
|
|
- public FixFragmentNavigator(@NonNull Context context, @NonNull FragmentManager manager, int containerId) {
|
|
|
- super(context, manager, containerId);
|
|
|
- mContext = context;
|
|
|
- mFragmentManager = manager;
|
|
|
- mContainerId = containerId;
|
|
|
- }
|
|
|
-
|
|
|
- @Nullable
|
|
|
- @Override
|
|
|
- public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
|
|
|
-
|
|
|
- if (mFragmentManager.isStateSaved()) {
|
|
|
- Log.i(TAG, "Ignoring navigate() call: FragmentManager has already"
|
|
|
- + " saved its state");
|
|
|
- return null;
|
|
|
- }
|
|
|
- String className = destination.getClassName();
|
|
|
- if (className.equals(oldClassName)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- oldClassName = className;
|
|
|
- if (className.charAt(0) == '.') {
|
|
|
- className = mContext.getPackageName() + className;
|
|
|
- }
|
|
|
- Fragment frag = mFragmentManager.findFragmentByTag(className);
|
|
|
- if (null == frag) {
|
|
|
- //不存在,则创建
|
|
|
- frag = instantiateFragment(mContext, mFragmentManager, className, args);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- frag.setArguments(args);
|
|
|
- final FragmentTransaction ft = mFragmentManager.beginTransaction();
|
|
|
-
|
|
|
- int enterAnim = navOptions != null ? navOptions.getEnterAnim() : -1;
|
|
|
- int exitAnim = navOptions != null ? navOptions.getExitAnim() : -1;
|
|
|
- int popEnterAnim = navOptions != null ? navOptions.getPopEnterAnim() : -1;
|
|
|
- int popExitAnim = navOptions != null ? navOptions.getPopExitAnim() : -1;
|
|
|
- if (enterAnim != -1 || exitAnim != -1 || popEnterAnim != -1 || popExitAnim != -1) {
|
|
|
- enterAnim = enterAnim != -1 ? enterAnim : 0;
|
|
|
- exitAnim = exitAnim != -1 ? exitAnim : 0;
|
|
|
- popEnterAnim = popEnterAnim != -1 ? popEnterAnim : 0;
|
|
|
- popExitAnim = popExitAnim != -1 ? popExitAnim : 0;
|
|
|
- ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim);
|
|
|
- }
|
|
|
-
|
|
|
-// ft.replace(mContainerId, frag);
|
|
|
- List<Fragment> fragments = mFragmentManager.getFragments();
|
|
|
- for (Fragment fragment : fragments) {
|
|
|
- ft.hide(fragment);
|
|
|
- }
|
|
|
- if (!frag.isAdded()) {
|
|
|
- ft.add(mContainerId, frag, className);
|
|
|
- }
|
|
|
-
|
|
|
- ft.show(frag);
|
|
|
- ft.setPrimaryNavigationFragment(frag);
|
|
|
-
|
|
|
- final @IdRes int destId = destination.getId();
|
|
|
-
|
|
|
- //通过反射获取mBackStack
|
|
|
- ArrayDeque<Integer> mBackStack;
|
|
|
- try {
|
|
|
- Field field = FragmentNavigator.class.getDeclaredField("mBackStack");
|
|
|
- field.setAccessible(true);
|
|
|
- mBackStack = (ArrayDeque<Integer>) field.get(this);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- final boolean initialNavigation = mBackStack.isEmpty();
|
|
|
- final boolean isSingleTopReplacement = navOptions != null && !initialNavigation
|
|
|
- && navOptions.shouldLaunchSingleTop()
|
|
|
- && mBackStack.peekLast() == destId;
|
|
|
-
|
|
|
- boolean isAdded;
|
|
|
- if (initialNavigation) {
|
|
|
- isAdded = true;
|
|
|
- } else if (isSingleTopReplacement) {
|
|
|
- if (mBackStack.size() > 1) {
|
|
|
- mFragmentManager.popBackStack(
|
|
|
- generateBackStackName(mBackStack.size(), mBackStack.peekLast()),
|
|
|
- FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
|
|
- ft.addToBackStack(generateBackStackName(mBackStack.size(), destId));
|
|
|
- }
|
|
|
- isAdded = false;
|
|
|
- } else {
|
|
|
- ft.addToBackStack(generateBackStackName(mBackStack.size() + 1, destId));
|
|
|
- isAdded = true;
|
|
|
- }
|
|
|
- if (navigatorExtras instanceof Extras) {
|
|
|
- Extras extras = (Extras) navigatorExtras;
|
|
|
- for (Map.Entry<View, String> sharedElement : extras.getSharedElements().entrySet()) {
|
|
|
- ft.addSharedElement(sharedElement.getKey(), sharedElement.getValue());
|
|
|
- }
|
|
|
- }
|
|
|
- ft.setReorderingAllowed(true);
|
|
|
- ft.commit();
|
|
|
- if (isAdded) {
|
|
|
- mBackStack.add(destId);
|
|
|
- return destination;
|
|
|
- } else {
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //navigate需要打方法重复类直接复制过来就可以
|
|
|
- @NonNull
|
|
|
- private String generateBackStackName(int backStackIndex, int destId) {
|
|
|
- return backStackIndex + "-" + destId;
|
|
|
- }
|
|
|
-}
|