如果你的业务涉及到列表上下滑动隐藏显示toolbar(标题栏)或者是你的悬浮按钮根据列表的滑动做上下隐藏,左右隐藏。(若是产品提出仿某b站上下滑动隐藏消失,仿某宝购物车移动上下滑动使其左右隐藏显示)那么恭喜你,直接发动 cc + cv 技能 完美完成需求,大家可以先看下下方实现的效果样式。
需要看代码的话直接点下方链接
github代码直通车
这边实现主要是根据 layout_scrollFlags 这个属性判断的,一共有5种属性
scroll Child View 伴随着滚动事件而滚出或滚进屏幕。注意两点:第一点,如果使用了其他值,必定要使用这个值才能起作用;第二点:如果在这个child View前面的任何其他Child View没有设置这个值,那么这个Child View的设置将失去作用。
enterAlways 它修改返回的视图,使其最初只滚动回它的折叠高度。一旦滚动视图到达滚动范围的末尾,该视图的其余部分将被滚动到视图中。折叠高度由视图的最小高度定义。
enterAlwaysCollapsed 退出(滚屏)时,视图将被滚动,直到它被“折叠”。
snap 在滚动结束时,如果视图只有部分可见,那么它将被抓取并滚动到最近的边缘。就是停止滚动时要么toolbar完全显示要么完全消失两种状态
exitUntilCollapsed 向上滚动时,toolbar向上滚动退出直至最小高度,然后 开始滚动。就是不会完全退出屏幕的意思。
这里主要用到 CoordinatorLayout.Behavior<View> 。我们根据监听滑动距离来做相应的处理,实现也很简单。
package com.hugh.basis.coordinatorLayoutPage.behavior; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.ViewCompat; import androidx.core.view.ViewPropertyAnimatorListener; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; /** * Created by chenyw on 2020/9/2. */ public class ViewRightInOutBehavior extends CoordinatorLayout.Behavior<View> { private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private boolean mAnimatingOut = false; public ViewRightInOutBehavior() { } public ViewRightInOutBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) { //需要垂直的滑动 return axes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type); } @Override public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); if (dyConsumed > 0 && !mAnimatingOut) { //向上滑动 animateOut(child); } else if (dyConsumed < 0) { //向下滑动 animateIn(child); } } private void animateOut(final View button) { ViewCompat.animate(button) .translationX(button.getWidth() + getMarginBottom(button)) .setInterpolator(INTERPOLATOR) .withLayer() .setListener(new ViewPropertyAnimatorListener() { public void onAnimationStart(View view) { mAnimatingOut = true; } public void onAnimationCancel(View view) { mAnimatingOut = false; } public void onAnimationEnd(View view) { mAnimatingOut = false; } }) .start(); } private void animateIn(View button) { ViewCompat.animate(button).translationX(0).setInterpolator(INTERPOLATOR).withLayer().setListener(null).start(); } private int getMarginBottom(View v) { final ViewGroup.LayoutParams layoutParams = v.getLayoutParams(); if (layoutParams instanceof ViewGroup.MarginLayoutParams) { return ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin; } return 0; } }在xml中使用上面的 behavior
<ImageView android:id="@+id/float_dub" android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="end|bottom" android:layout_marginEnd="20dp" android:layout_marginBottom="20dp" android:src="@android:drawable/ic_dialog_info" app:layout_behavior=".coordinatorLayoutPage.behavior.ViewBottomInOutBehavior" tools:visibility="visible" />onStartNestedScroll() onNestedScrollAccepted() onStopNestedScroll() onNestedScroll() onNestedPreScroll() onNestedFling() onNestedPreFling()
这上述功能中主要实现 onNestedScroll方法 ,提供给我们相应的滑动距离给予我们做业务判断
xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" android:background="@color/white"> <androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/layout_cooRoot" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp"> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/white" android:contentInsetStart="0dp" app:contentInsetStart="0dp" app:layout_scrollFlags="scroll|enterAlways|snap" app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/actionBar" android:layout_width="match_parent" android:layout_height="44dp" android:layout_below="@+id/view_hold" android:background="@color/white"> <LinearLayout android:id="@+id/layout_search" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:background="@drawable/oval_c8" android:gravity="center" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_weight="1" app:layout_constraintRight_toLeftOf="@+id/iv_history" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <TextView android:id="@+id/tv_search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableLeft="@drawable/home_icon_searchnew" android:drawablePadding="4dp" android:gravity="center" android:paddingTop="7dp" android:paddingBottom="7dp" android:text="哈哈哈哈哈搜索" android:textColor="@color/c5" android:textSize="14sp" /> </LinearLayout> <ImageView android:id="@+id/iv_history" android:layout_width="26dp" android:layout_height="26dp" android:layout_centerInParent="true" android:layout_marginRight="13dp" android:scaleType="center" android:src="@color/yellow" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toLeftOf="@+id/iv_message" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/iv_message" android:layout_width="26dp" android:layout_height="26dp" android:layout_centerInParent="true" android:layout_marginRight="13dp" android:scaleType="center" android:src="@color/yellow" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.appcompat.widget.Toolbar> </com.google.android.material.appbar.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:gravity="center_horizontal" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <net.lucode.hackware.magicindicator.MagicIndicator android:id="@+id/magic_indicator1" android:layout_width="match_parent" android:layout_height="44dp" android:background="@android:color/white" /> <androidx.viewpager.widget.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/magic_indicator1" android:flipInterval="30" android:persistentDrawingCache="animation" /> </LinearLayout> <ImageView android:id="@+id/img_float_ad" android:layout_width="80dp" android:layout_height="80dp" android:layout_gravity="center|end" android:src="@android:drawable/ic_dialog_email" app:layout_behavior=".coordinatorLayoutPage.behavior.ViewRightInOutBehavior" tools:background="@color/c6" tools:visibility="visible" /> <ImageView android:id="@+id/float_dub" android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="end|bottom" android:layout_marginEnd="20dp" android:layout_marginBottom="20dp" android:src="@android:drawable/ic_dialog_info" app:layout_behavior=".coordinatorLayoutPage.behavior.ViewBottomInOutBehavior" tools:visibility="visible" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </FrameLayout>需要上述整体实现逻辑的话可以直接点 github代码直通车