效果图

布局代码
<FrameLayout
android:paddingHorizontal="@dimen/dp_13"
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_353">
<com.hjq.shape.layout.ShapeLinearLayout
android:layout_width="match_parent"
app:shape_solidColor="@color/blue"
app:shape_radius="@dimen/dp_32"
android:translationY="@dimen/dp_101"
android:layout_height="@dimen/dp_252"/>
<com.hjq.shape.layout.ShapeLinearLayout
android:layout_width="match_parent"
app:shape_solidColor="@color/red"
app:shape_radius="@dimen/dp_32"
android:translationY="@dimen/dp_50"
android:layout_height="@dimen/dp_252"/>
<com.hjq.shape.layout.ShapeLinearLayout
android:layout_width="match_parent"
app:shape_solidColor="@color/green"
app:shape_radius="@dimen/dp_32"
android:layout_height="@dimen/dp_252"/>
</FrameLayout>
核心代码
override fun initData() {
views.add(mLlGj)
views.add(mLlZb)
views.add(mLlHj)
views.forEach { view ->
view.setOnClickListener {
if (!isAnimating) {
cycleViews(views.indexOf(view))
}
}
}
}
private fun cycleViews(position: Int) {
if (position == 0) return
isAnimating = true
val duration = 400L
val interpolator = OvershootInterpolator(1.5f)
views.forEachIndexed { index, view ->
if (index == position) {
view.elevation = 6f.dp
} else{
view.elevation = 2f.dp
}
}
if (position == 1) {
views[1].animate()
.translationY(0f)
.setDuration(duration)
.setInterpolator(interpolator)
.start()
views.first().animate()
.translationY(50f.dp)
.setDuration(duration)
.setInterpolator(interpolator)
.withEndAction {
views.add(0, views.removeAt(position))
resetViewElevation()
isAnimating = false
}
.start()
} else if (position == 2) {
views.last().animate()
.translationY(0f)
.setDuration(duration)
.setInterpolator(interpolator)
.start()
views[1].animate()
.translationY(101f.dp)
.setDuration(duration)
.setInterpolator(interpolator)
.start()
views.first().animate()
.translationY(50f.dp)
.setDuration(duration)
.setInterpolator(interpolator)
.withEndAction {
views.add(0, views.removeAt(position))
resetViewElevation()
isAnimating = false
}
.start()
}
}
private fun resetViewElevation() {
views.forEachIndexed { index, view ->
view.elevation = when(index) {
0 -> 6f.dp
1 -> 4f.dp
else -> 2f.dp
}
}
}