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);
}
@Override
public void navigate(@NonNull List<NavBackStackEntry> entries, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
navOptions = NavUtils.adjustDefaultAnim(navOptions);
super.navigate(entries, navOptions, navigatorExtras);
}
@Nullable
@Override
public 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 {
@Override
protected void onCreateNavHostController(@NonNull NavHostController navHostController) {
super.onCreateNavHostController(navHostController);
}
@NonNull
@Override
protected 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.FragmentContainerView
android: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>
然后正常调用导航方法即可,在没有明确设置跳转动画时,会添加默认动画,也可以指定跳转动画。