如果要获得类似gif的动画效果,甚至更好的效果,则可以使用新的MotionLayout
的要旨是创建两个状态并在motion scene
中滑动动作。 MotionLayout
将负责所有工作。
您的布局文件(仅用于标题。您基本上可以在布局文件中定义起始状态)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/sample_collapsing_animation_scene">
<View
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/md_green_300" />
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/md_white_1000"
android:elevation="4dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="36dp"
android:layout_marginEnd="36dp"
android:layout_marginTop="40dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/your_scrolling_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
您的运动场景(定义状态和滑动触发器的位置)
<?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">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="@id/your_scrolling_content"
motion:touchAnchorSide="top" />
<OnSwipe />
</Transition>
<ConstraintSet android:id="@+id/start">
/** Very simple animation no need for start state*/
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="24dp"
android:elevation="4dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp" />
</ConstraintSet>
</MotionScene>
这就是您所需要的,但在实际应用中,情况可能会有所不同。
这里是MotionLayout
的链接
[MotionLayout
是使用运动布局创建Here感觉的很好参考。
您可以使用两个搜索视图(一个在工具栏内,另一个在工具栏下方)来实现。在您的布局中:
CollapsingToolbar
然后在您的活动中,在其下方的搜索视图在屏幕中上下滚动时,在工具栏中切换搜索的可见性。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ScrollSearchActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
app:title=""
app:menu="@menu/main_menu"
android:background="@color/colorPrimary"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/toolbar_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@mipmap/ic_launcher"/>
<androidx.appcompat.widget.SearchView
android:id="@+id/toolbar_searchview"
android:visibility="gone"
android:layout_width="300dp"
android:layout_height="40dp"
android:background="@color/ms_white"/>
</FrameLayout>
</androidx.appcompat.widget.Toolbar>
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:padding="4dp">
<androidx.appcompat.widget.SearchView
android:id="@+id/searchview"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="4dp"
android:background="@color/ms_white"/>
</FrameLayout>
//the rest of your activity's content goes here
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
您应该得到这样的东西:
class ScrollSearchActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scroll_search)
scroll_view.setOnScrollChangeListener { view, scrollX, scrollY, oldScrollX, oldScrollY ->
val isSearchViewVisible = scroll_view.isViewVisible(searchview)
toolbar_searchview.visibility = if(isSearchViewVisible) View.GONE else View.VISIBLE
toolbar_icon.visibility = if(isSearchViewVisible) View.VISIBLE else View.GONE
}
}
private fun ScrollView.isViewVisible(view: View): Boolean {
val scrollBounds = Rect()
this.getDrawingRect(scrollBounds)
var top = 0f
var temp = view
while (temp !is ScrollView){
top += (temp).y
temp = temp.parent as View
}
val bottom = top + view.height
return scrollBounds.top < bottom && scrollBounds.bottom > top
}
}