Android ConstraintLayout中粒子动画置于ImageView背景的实现问题
解决Leonids粒子动画盖在ImageView上方的问题
我之前也碰到过这个坑!Leonids默认会把粒子动画挂载到Activity的Window DecorView上——这可是整个界面的最顶层,所以不管你给ImageView设置多高的elevation,粒子都会妥妥地盖在上面。
下面是我亲测有效的解决方法:
步骤1:给动画加个底层容器(可选但更清晰)
在你的ConstraintLayout最顶部(布局代码里的最前面,因为ConstraintLayout里先声明的View层级更低)加一个全屏的空View,专门用来承载粒子动画:
<android.support.constraint.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/bg_splash" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_splashscreen"> <!-- 新增:粒子动画的专属底层容器 --> <View android:id="@+id/particle_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <!-- 你的原有ImageView --> <ImageView android:id="@+id/logo_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="36dp" android:layout_marginStart="37dp" android:layout_marginTop="8dp" android:src="@drawable/logo" android:elevation="4dp" app:layout_constraintBottom_toTopOf="@+id/guideline2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_weight="0.1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline" app:layout_constraintVertical_weight="0.1" tools:ignore="ContentDescription" /> <android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.26371" /> <android.support.constraint.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.42074" /> </android.support.constraint.ConstraintLayout>
步骤2:修改动画代码,指定父容器
关键一步!创建ParticleSystem后,调用setParentView()方法,把粒子动画挂载到刚才新增的容器上,而不是默认的DecorView:
fun particleConfettiAnimation(fromActivity: Activity?) { if (fromActivity == null){ return } // 获取我们新增的粒子容器 val particleContainer = fromActivity.findViewById<View>(R.id.particle_container) ParticleSystem(fromActivity, 80, R.drawable.confetti, 10000) .setSpeedModuleAndAngleRange(0f, 0.3f, 0, 0) .setRotationSpeed(144f) .setAcceleration(0.00035f, 100) .setParentView(particleContainer) // 这行是核心,改变动画的挂载层级 .emit(100, -100, 5) }
为什么这样有效?
原来的粒子动画是直接加到整个窗口的最顶层,现在我们把它限制在particle_container这个View里,而这个容器在布局里是第一个声明的,ConstraintLayout会自动把它放在所有后续View的底层。再加上你给ImageView设置的elevation="4dp",完全可以确保Logo显示在粒子动画的上方。
如果不想新增容器,也可以直接把粒子挂载到bg_splash这个ConstraintLayout本身,但用专门的容器管理动画会更清晰,也避免和其他View的层级冲突。
内容的提问来源于stack exchange,提问作者Manu13k
相关产品推荐
相关产品推荐

