| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- 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;
- }
- }
|