You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Android应用中Fragment的页面切换添加翻书动画?

实现Fragment切换的翻书动画方案

针对书籍类应用的Fragment切换翻书效果,以下是两种常见场景的实现方案,核心是利用Android的3D变换和动画系统模拟真实翻书的视觉效果:

场景1:ViewPager + Fragment 实现左右翻书切换

如果你的页面是通过ViewPager管理的横向Fragment列表,使用PageTransformer是最便捷的方式,它能直接控制每个页面的变换逻辑:

自定义翻书PageTransformer

public class BookFlipPageTransformer implements ViewPager.PageTransformer {
    private Camera camera = new Camera();
    private static final float MIN_SCALE = 0.75f; // 页面最小缩放比例

    @Override
    public void transformPage(@NonNull View page, float position) {
        int pageWidth = page.getWidth();
        int pageHeight = page.getHeight();

        if (position < -1) { // 左侧完全不可见的页面
            page.setAlpha(0f);
        } else if (position <= 0) { // 当前页面向左滑动,或左侧页面进入视野
            page.setAlpha(1f);
            page.setTranslationX(0f);
            page.setScaleX(1f);
            page.setScaleY(1f);

            // 3D绕Y轴旋转,模拟翻书的左侧翻页效果
            camera.save();
            camera.translate(0, 0, 100); // 调整Z轴距离增强立体感
            camera.rotateY(position * 180);
            camera.getMatrix(page.getMatrix());
            camera.restore();
        } else if (position <= 1) { // 当前页面向右滑动,或右侧页面进入视野
            page.setAlpha(1 - position);
            // 调整页面位置,模拟翻书时的重叠效果
            page.setTranslationX(pageWidth * -position);
            // 缩放页面,增强远近层次感
            float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
            page.setScaleX(scaleFactor);
            page.setScaleY(scaleFactor);

            // 反向3D旋转,模拟右侧翻页效果
            camera.save();
            camera.translate(0, 0, 100);
            camera.rotateY((position - 1) * 180);
            camera.getMatrix(page.getMatrix());
            camera.restore();
        } else { // 右侧完全不可见的页面
            page.setAlpha(0f);
        }
    }
}

绑定到ViewPager

在初始化ViewPager时设置这个Transformer:

ViewPager viewPager = findViewById(R.id.book_view_pager);
viewPager.setPageTransformer(true, new BookFlipPageTransformer());
// 后续设置Adapter等逻辑不变

场景2:手动FragmentTransaction切换时的翻书动画

如果是通过replace()/add()手动切换单个Fragment,需要自定义属性动画来控制Fragment的进出效果:

定义动画资源文件

在res/animator目录下创建两个动画文件:

  • book_flip_enter.xml(新Fragment进入动画):
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="rotationY"
        android:valueFrom="180"
        android:valueTo="0"
        android:duration="500"
        android:interpolator="@android:interpolator/decelerate_cubic"/>
    <objectAnimator
        android:propertyName="translationZ"
        android:valueFrom="50dp"
        android:valueTo="0dp"
        android:duration="500"/>
    <objectAnimator
        android:propertyName="scaleX"
        android:valueFrom="0.8"
        android:valueTo="1"
        android:duration="500"/>
    <objectAnimator
        android:propertyName="scaleY"
        android:valueFrom="0.8"
        android:valueTo="1"
        android:duration="500"/>
</set>
  • book_flip_exit.xml(旧Fragment退出动画):
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="rotationY"
        android:valueFrom="0"
        android:valueTo="-180"
        android:duration="500"
        android:interpolator="@android:interpolator/decelerate_cubic"/>
    <objectAnimator
        android:propertyName="translationZ"
        android:valueFrom="0dp"
        android:valueTo="50dp"
        android:duration="500"/>
    <objectAnimator
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.8"
        android:duration="500"/>
    <objectAnimator
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.8"
        android:duration="500"/>
</set>

应用到FragmentTransaction

切换Fragment时设置自定义动画:

getSupportFragmentManager().beginTransaction()
        .setCustomAnimations(R.animator.book_flip_enter, R.animator.book_flip_exit)
        .replace(R.id.fragment_container, new TargetBookFragment())
        .addToBackStack(null) // 可选,需要返回栈时添加
        .commit();

效果优化建议

  • 调整Camera的Z轴参数:修改camera.translate(0, 0, 100)中的数值,越大立体感越强,但可能导致页面变形,需根据实际UI调整。
  • 添加动态阴影:可以在翻书过程中通过View.setElevation()动态调整阴影大小,或者自定义Drawable模拟翻书时的阴影渐变。
  • 手势支持:配合GestureDetector监听左右滑动手势,触发Fragment切换,让交互更符合书籍阅读习惯。
  • 硬件加速:确保Activity或View开启硬件加速(默认开启),避免3D变换导致的卡顿。

内容的提问来源于stack exchange,提问作者user19346309

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:01:09