国际惯例:效果图(来自网络,侵删)html
其实主要用的就是CoordinatorLayout+Behaviorjava
首先自定义Behaviorandroid
import android.animation.Animator; import android.content.Context; import android.support.annotation.NonNull; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.ViewCompat; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.util.AttributeSet; import android.view.View; import android.view.ViewPropertyAnimator; import android.view.animation.Interpolator; /** * 做者:yedajiang44 * 时间 2018-01-11 16:47 * 说明:自定义Behavior */ public class BottomBarBehavior extends CoordinatorLayout.Behavior<View> { private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private float viewY;//控件距离coordinatorLayout底部距离 private boolean isAnimate;//动画是否在进行 public BottomBarBehavior(Context context, AttributeSet attrs) { super(context, attrs); } /** * 有嵌套滑动到来了,问下该Behavior是否接受嵌套滑动 * * @param coordinatorLayout 当前的CoordinatorLayout * @param child 该Behavior对应的View * @param directTargetChild 个人理解是在CoordinateLayout下做为父View,而该View的子类是Tager的那个View,也就是Target的父View),由于我测试用ViewPager包裹了RecycleView后该参数返回Viewpager,若是没有包裹参数返回的是RecycleView * @param target 具体嵌套滑动的那个子类 * @param nestedScrollAxes 支持嵌套滚动轴。水平方向,垂直方向,或者不指定 * @param type 致使此滚动事件的输入类型 * @return 是否接受该嵌套滑动 */ @Override public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int nestedScrollAxes, @ViewCompat.NestedScrollType int type) { if (child.getVisibility() == View.VISIBLE && viewY == 0) { //获取控件距离父布局(coordinatorLayout)底部距离 viewY = coordinatorLayout.getHeight() - child.getY(); } //ViewCompat是一个兼容类,在android5.0以前的API为了实现新的效果 //避免出错使用ViewCompat.xxxx方法能够解决出现低版本错误的问题 return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;//判断是否竖直滚动 } /** * 在嵌套滑动的子View未滑动以前准备滑动的状况 (待修改) * * @param coordinatorLayout 此行为与关联的视图的父级CoordinatorLayout * @param child 该Behavior对应的View * @param target 具体嵌套滑动的那个子类 * @param dx 水平方向嵌套滑动的子View想要变化的距离 * @param dy 垂直方向嵌套滑动的子View想要变化的距离 * @param consumed 这个参数要咱们在实现这个函数的时候指定,回头告诉子View当前父View消耗的距离 consumed[0] 水平消耗的距离,consumed[1] 垂直消耗的距离 好让子view作出相应的调整 * @param type 致使此滚动事件的输入类型 */ @Override public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type); //dy大于0是向上滚动 小于0是向下滚动,判断的时候尽可能不要判断是否大于等于或者小于等于0,不然可能会影响点击事件 //System.out.println(dy); if (type == ViewCompat.TYPE_TOUCH) { if (dy > 20 && !isAnimate && child.getVisibility() == View.VISIBLE) { hide(child); } else if (dy < 20 && !isAnimate && child.getVisibility() == View.INVISIBLE) { show(child); } } } //隐藏时的动画 private void hide(final View view) { ViewPropertyAnimator animator = view.animate().translationY(viewY).setInterpolator(INTERPOLATOR).setDuration(500); animator.setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { isAnimate = true; } @Override public void onAnimationEnd(Animator animator) { view.setVisibility(View.INVISIBLE); isAnimate = false; } @Override public void onAnimationCancel(Animator animator) { show(view); } @Override public void onAnimationRepeat(Animator animator) { } }); animator.start(); } //显示时的动画 private void show(final View view) { ViewPropertyAnimator animator = view.animate().translationY(0).setInterpolator(INTERPOLATOR).setDuration(500); animator.setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { view.setVisibility(View.VISIBLE); isAnimate = true; } @Override public void onAnimationEnd(Animator animator) { isAnimate = false; } @Override public void onAnimationCancel(Animator animator) { hide(view); } @Override public void onAnimationRepeat(Animator animator) { } }); animator.start(); } }
自定义好了Behavior以后就须要在layout布局文件里使用了网络
layout布局:app
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" android:minHeight="?attr/actionBarSize" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/activity_dyeOrder_detail_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" app:layout_scrollFlags="scroll|enterAlways" app:navigationIcon="@mipmap/ic_arrow_back_white_24dp" app:popupTheme="@style/AppTheme.PopupOverlay" app:title="@string/dyeOrderDetail" /> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v7.widget.RecyclerView android:id="@+id/dyeMessageList" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="beforeDescendants" android:scrollbars="vertical" tools:listitem="@layout/recycle_no_dye_message_entry_list" /> </android.support.v4.widget.SwipeRefreshLayout> <LinearLayout android:id="@+id/addLayout" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:gravity="center" android:orientation="horizontal" android:background="@color/white" app:layout_behavior="BottomBarBehavior" app:layout_anchor="@id/swipeRefreshLayout" app:layout_anchorGravity="bottom|end"> <TextView android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="底部菜单" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout>须要注意的是app:layout_behavior="BottomBarBehavior"中的BottomBarBehavior若是不在根目录须要加上包名