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

求助:实现Prisma应用中CAMERA与FEED间全屏Fragment及透明TabLayout动画

嘿,我刚好折腾过类似的Prisma风格页面切换动画,给你梳理几个可行的实现步骤,一步步来搞定:

核心需求拆解

咱们要实现的是三个关键点:Fragment全屏显示 + TabLayout透明化 + 页面切换时的缩放位移动画,下面逐个击破。

一、先搞定TabLayout透明化

  • 直接在布局文件里给TabLayout设置透明背景,同时适配文字颜色避免看不见:
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        app:tabTextColor="#FFFFFF"
        app:tabSelectedTextColor="#FFD700" />
    
  • 如果TabLayout嵌套在AppBarLayout里,记得把AppBarLayout的背景也设为透明,避免出现遮挡。

二、设置Fragment全屏显示

  • 给Fragment的根布局添加android:fitsSystemWindows="true",让内容自动适配状态栏高度,避免被挡住。
  • 布局结构建议用ConstraintLayout或FrameLayout,把TabLayout叠加在Fragment内容上方,给TabLayout设置android:elevation="4dp"保证层级在Fragment之上,同时让ViewPager/Fragment容器占满整个屏幕空间。
  • 记得在Activity里隐藏默认ActionBar,或者把主题设置为NoActionBar。

三、实现核心的页面切换动画

这部分是Prisma效果的灵魂,推荐两种方案,根据你的页面管理方式选择:

方案1:用ViewPager2的PageTransformer(适合ViewPager管理页面)

自定义一个PageTransformer,实现滑动时的缩放+位移效果,匹配Prisma的动画风格:

class PrismaPageTransformer : ViewPager2.PageTransformer {
    private val MIN_SCALE = 0.85f // 最小缩放比例
    private val MIN_ALPHA = 0.0f // 最小透明度

    override fun transformPage(page: View, position: Float) {
        page.apply {
            when {
                position < -1 -> { // 页面完全滑出左侧
                    alpha = MIN_ALPHA
                    scaleX = MIN_SCALE
                    scaleY = MIN_SCALE
                }
                position <= 0 -> { // 从左滑入/滑出到左的过程
                    alpha = MIN_ALPHA + (1 + position) * (1 - MIN_ALPHA)
                    val scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position))
                    scaleX = scaleFactor
                    scaleY = scaleFactor
                    translationX = width * -position * 0.3f // 增加轻微位移增强层次感
                }
                position <= 1 -> { // 从右滑入/滑出到右的过程
                    alpha = MIN_ALPHA + (1 - position) * (1 - MIN_ALPHA)
                    val scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - position)
                    scaleX = scaleFactor
                    scaleY = scaleFactor
                    translationX = width * -position * 0.3f
                }
                else -> { // 页面完全滑出右侧
                    alpha = MIN_ALPHA
                    scaleX = MIN_SCALE
                    scaleY = MIN_SCALE
                }
            }
        }
    }
}

然后给ViewPager2设置这个Transformer:

viewPager2.setPageTransformer(PrismaPageTransformer())

方案2:用FragmentTransaction自定义动画(适合手动切换Fragment)

如果是用FragmentManager手动切换页面,先在res/anim目录下创建两个动画文件:

  • slide_in_right.xml(右侧页面滑入):
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
    <translate android:fromXDelta="100%" android:toXDelta="0%" android:duration="300"/>
    <scale android:fromXScale="0.85" android:toXScale="1.0" android:pivotX="50%" android:pivotY="50%" android:duration="300"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300"/>
</set>
  • slide_out_left.xml(左侧页面滑出):
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
    <translate android:fromXDelta="0%" android:toXDelta="-30%" android:duration="300"/>
    <scale android:fromXScale="1.0" android:toXScale="0.85" android:pivotX="50%" android:pivotY="50%" android:duration="300"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300"/>
</set>

切换Fragment时调用:

supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right, // 进入动画
        R.anim.slide_out_left, // 退出动画
        R.anim.slide_in_left, // 反向进入(返回时)
        R.anim.slide_out_right // 反向退出(返回时)
    )
    .replace(R.id.fragment_container, targetFragment)
    .addToBackStack(null)
    .commit()

四、额外优化小技巧

  • 如果想让TabLayout在滑动时也有轻微的透明度变化,增强联动效果,可以给ViewPager2添加页面监听:
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
        // 滑动过程中TabLayout透明度在0.8到1之间变化,可根据需求调整
        tabLayout.alpha = 1f - Math.abs(positionOffset - 0.5f) * 0.2f
    }
})
  • 处理状态栏适配:在Activity中调用WindowCompat.setDecorFitsSystemWindows(window, false),然后在Fragment布局的根节点添加android:paddingTop="@dimen/status_bar_height"(需要自己定义状态栏高度的dimen值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:42:05