MotionLayout + RecyclerView 需要做一些額外的處理才能有類似嵌套滑動(dòng)的聯(lián)動(dòng)效果。
start_layout
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/activity_main_scene">
<TextView
android:id="@+id/textView2"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#999"
android:gravity="center"
android:text="返回"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#999"
android:gravity="center"
android:text="標(biāo)題"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<TextView
android:id="@+id/tvSearch"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="#666"
android:gravity="center_vertical"
android:hint="搜索"
android:paddingStart="15dp"
android:paddingEnd="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvTitle"
app:layout_constraintVertical_bias="0" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSearch" />
</androidx.constraintlayout.motion.widget.MotionLayout>
scene
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="10000">
<KeyFrameSet>
</KeyFrameSet>
<OnSwipe motion:nestedScrollFlags="supportScrollUp" motion:autoCompleteMode="continuousVelocity" motion:dragDirection="dragUp"
motion:touchAnchorId="@id/rv"http://劃重點(diǎn)
/>
</Transition>
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/tvTitle"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="100dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintVertical_bias="0"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
android:visibility="gone" />
<Constraint
android:id="@+id/tvSearch"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"
android:layout_height="50dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintVertical_bias="0"
motion:layout_constraintTop_toBottomOf="@id/tvTitle"
motion:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="50dp" />
<Constraint
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toBottomOf="@id/tvSearch"
motion:layout_constraintStart_toStartOf="parent"
android:id="@+id/rv"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp" />
</ConstraintSet>
</MotionScene>
代碼處理:
binding.rv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if(dy>0){
if( binding.motionLayout.currentState== binding.motionLayout.startState){
binding.motionLayout.transitionToEnd()
}
}else{
if( binding.motionLayout.currentState== binding.motionLayout.endState) {
binding.motionLayout.transitionToStart()
}
}
}
})