LinearLayout设置android:animateLayoutChanges=true在ViewPager2中不生效问题
问题根因
- ViewPager2默认属性
transitionGroup=true,会拦截所有子View层级的布局过渡动画,直接导致XML配置的android:animateLayoutChanges属性失效 - 嵌套在ViewPager2内部的RecyclerView,系统为了避免页面切换动画和列表item动画产生冲突,会默认禁用部分布局过渡能力
- XML中配置的
animateLayoutChanges默认仅开启基础的视图显隐过渡,未开启布局位置变更类过渡,在嵌套滚动容器中极易被系统拦截
解决方案
方案1:手动给自定义布局开启完整布局过渡
在自定义View的构造方法中手动配置LayoutTransition,替换XML的animateLayoutChanges属性:
// Kotlin 示例 init { val root = LayoutInflater.from(context).inflate(R.layout.your_custom_layout, this, true) val linearLayout = root.findViewById<LinearLayout>(R.id.deliveryByLayout) // 手动创建布局过渡实例,开启所有过渡类型 val layoutTransition = LayoutTransition() layoutTransition.enableTransitionType(LayoutTransition.CHANGING) layoutTransition.enableTransitionType(LayoutTransition.APPEARING) layoutTransition.enableTransitionType(LayoutTransition.DISAPPEARING) layoutTransition.enableTransitionType(LayoutTransition.CHANGE_APPEARING) layoutTransition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING) linearLayout.layoutTransition = layoutTransition }
// Java 示例 public YourCustomView(Context context, AttributeSet attrs) { super(context, attrs); View root = LayoutInflater.from(context).inflate(R.layout.your_custom_layout, this, true); LinearLayout linearLayout = root.findViewById(R.id.deliveryByLayout); LayoutTransition layoutTransition = new LayoutTransition(); layoutTransition.enableTransitionType(LayoutTransition.CHANGING); layoutTransition.enableTransitionType(LayoutTransition.APPEARING); layoutTransition.enableTransitionType(LayoutTransition.DISAPPEARING); layoutTransition.enableTransitionType(LayoutTransition.CHANGE_APPEARING); layoutTransition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING); linearLayout.setLayoutTransition(layoutTransition); }
方案2:关闭ViewPager2的过渡拦截
给ViewPager2设置transitionGroup=false,允许子布局触发过渡动画:
XML配置:
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:transitionGroup="false"/>
代码配置:
viewPager2.isTransitionGroup = false
方案3:替换为手动属性动画(兼容性最优)
如果以上方案都无效,直接弃用系统animateLayoutChanges,自己实现显隐动画,完全不受父容器影响:
// 显隐TextView的点击事件示例 imageView.setOnClickListener { if (textView.visibility == View.GONE) { // 显示动画 textView.apply { visibility = View.VISIBLE alpha = 0f translationX = -20f animate() .alpha(1f) .translationX(0f) .setDuration(300) .start() } } else { // 隐藏动画 textView.animate() .alpha(0f) .translationX(-20f) .setDuration(300) .withEndAction { textView.visibility = View.GONE } .start() } }
内容的提问来源于stack exchange,提问作者Muhammad Hamza
相关产品推荐
相关产品推荐

