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>
然后正常調用導航方法即可,在沒有明確設置跳轉動畫時,會添加默認動畫,也可以指定跳轉動畫。