Activity的跳转一般通过Theme设置即可,但是Framment的跳转除了NavigationUI类提供的方法会有动画以外,直接调用navigate方法是没有动画的。
网上的实现个人认为比较麻烦,帮自己写了一套,主要就是自定义NavHostFragement和FragmentNavigator,设置上自定义的动画:
import android.content.Context;
import android.os.Bundle;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavBackStackEntry;
import androidx.navigation.NavDestination;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigator;
import androidx.navigation.fragment.FragmentNavigator;import java.util.List;@Navigator.Name("fragment")
public class DefFragmentNavigator extends FragmentNavigator {public DefFragmentNavigator(@NonNull Context context, @NonNull FragmentManager fragmentManager, int containerId) {super(context, fragmentManager, containerId);}@Overridepublic void navigate(@NonNull List<NavBackStackEntry> entries, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {navOptions = NavUtils.adjustDefaultAnim(navOptions);super.navigate(entries, navOptions, navigatorExtras);}@Nullable@Overridepublic NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {navOptions = NavUtils.adjustDefaultAnim(navOptions);return super.navigate(destination, args, navOptions, navigatorExtras);}
}
import android.view.View;import androidx.annotation.NonNull;
import androidx.navigation.NavHostController;
import androidx.navigation.Navigator;
import androidx.navigation.fragment.FragmentNavigator;
import androidx.navigation.fragment.NavHostFragment;public class DefNavHostFragment extends NavHostFragment {@Overrideprotected void onCreateNavHostController(@NonNull NavHostController navHostController) {super.onCreateNavHostController(navHostController);}@NonNull@Overrideprotected Navigator<? extends FragmentNavigator.Destination> createFragmentNavigator() {return new DefFragmentNavigator(requireContext(), getChildFragmentManager(), getContainerId());}private int getContainerId() {int id = getId();if (id != 0 && id != View.NO_ID) {return id;} else {return R.id.nav_host_fragment_container;}// Fallback to using our own ID if this Fragment wasn't added via// add(containerViewId, Fragment)}
}
import androidx.navigation.NavOptions;public class NavUtils {private static final NavOptions.Builder builder = new NavOptions.Builder().setEnterAnim(R.anim.left_slide_in).setExitAnim(R.anim.no_anim).setPopEnterAnim(R.anim.no_anim).setPopExitAnim(R.anim.left_slide_out);public static NavOptions defaultNavOptions = builder.build();/*** 自定义跳转又想带默认动画的,应使用此方法创建基础builder*/public static NavOptions.Builder navBuilder() {return builder;}public static NavOptions adjustDefaultAnim(NavOptions navOptions) {if (navOptions == null) {navOptions = defaultNavOptions;}return navOptions;}}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragmentContainer"android:layout_width="match_parent"android:layout_height="match_parent"android:name="com.****.DefNavHostFragment"app:defaultNavHost="true"app:navGraph="@navigation/nav_main"/></androidx.constraintlayout.widget.ConstraintLayout>
然后正常调用导航方法即可,在没有明确设置跳转动画时,会添加默认动画,也可以指定跳转动画。