CoordinatorLayout實現底部菜單滑動顯示與隱藏

國際慣例:效果圖(來自網絡,侵刪)html

其實主要用的就是CoordinatorLayout+Behaviorjava

首先自定義Behaviorandroid

[java]  view plain  copy
  1. import android.animation.Animator;  
  2. import android.content.Context;  
  3. import android.support.annotation.NonNull;  
  4. import android.support.design.widget.CoordinatorLayout;  
  5. import android.support.v4.view.ViewCompat;  
  6. import android.support.v4.view.animation.FastOutSlowInInterpolator;  
  7. import android.util.AttributeSet;  
  8. import android.view.View;  
  9. import android.view.ViewPropertyAnimator;  
  10. import android.view.animation.Interpolator;  
  11.   
  12. /** 
  13.  * 做者:yedajiang44 
  14.  * 時間 2018-01-11 16:47 
  15.  * 說明:自定義Behavior 
  16.  */  
  17.   
  18. public class BottomBarBehavior extends CoordinatorLayout.Behavior<View> {  
  19.     private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();  
  20.   
  21.     private float viewY;//控件距離coordinatorLayout底部距離  
  22.     private boolean isAnimate;//動畫是否在進行  
  23.   
  24.     public BottomBarBehavior(Context context, AttributeSet attrs) {  
  25.         super(context, attrs);  
  26.     }  
  27.   
  28.     /** 
  29.      * 有嵌套滑動到來了,問下該Behavior是否接受嵌套滑動 
  30.      * 
  31.      * @param coordinatorLayout 當前的CoordinatorLayout 
  32.      * @param child             該Behavior對應的View 
  33.      * @param directTargetChild 個人理解是在CoordinateLayout下做爲父View,而該View的子類是Tager的那個View,也就是Target的父View),由於我測試用ViewPager包裹了RecycleView後該參數返回Viewpager,若是沒有包裹參數返回的是RecycleView 
  34.      * @param target            具體嵌套滑動的那個子類 
  35.      * @param nestedScrollAxes  支持嵌套滾動軸。水平方向,垂直方向,或者不指定 
  36.      * @param type              致使此滾動事件的輸入類型 
  37.      * @return 是否接受該嵌套滑動 
  38.      */  
  39.   
  40.     @Override  
  41.     public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int nestedScrollAxes, @ViewCompat.NestedScrollType int type) {  
  42.         if (child.getVisibility() == View.VISIBLE && viewY == 0) {  
  43.             //獲取控件距離父佈局(coordinatorLayout)底部距離  
  44.             viewY = coordinatorLayout.getHeight() - child.getY();  
  45.         }  
  46.   
  47.         //ViewCompat是一個兼容類,在android5.0以前的API爲了實現新的效果  
  48.         //避免出錯使用ViewCompat.xxxx方法能夠解決出現低版本錯誤的問題  
  49.         return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;//判斷是否豎直滾動  
  50.     }  
  51.   
  52.   
  53.     /** 
  54.      * 在嵌套滑動的子View未滑動以前準備滑動的狀況  (待修改) 
  55.      * 
  56.      * @param coordinatorLayout 此行爲與關聯的視圖的父級CoordinatorLayout 
  57.      * @param child             該Behavior對應的View 
  58.      * @param target            具體嵌套滑動的那個子類 
  59.      * @param dx                水平方向嵌套滑動的子View想要變化的距離 
  60.      * @param dy                垂直方向嵌套滑動的子View想要變化的距離 
  61.      * @param consumed          這個參數要咱們在實現這個函數的時候指定,回頭告訴子View當前父View消耗的距離 consumed[0] 水平消耗的距離,consumed[1] 垂直消耗的距離 好讓子view作出相應的調整 
  62.      * @param type              致使此滾動事件的輸入類型 
  63.      */  
  64.     @Override  
  65.     public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {  
  66.         super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);  
  67.         //dy大於0是向上滾動 小於0是向下滾動,判斷的時候儘可能不要判斷是否大於等於或者小於等於0,不然可能會影響點擊事件  
  68.         //System.out.println(dy);  
  69.         if (type == ViewCompat.TYPE_TOUCH) {  
  70.             if (dy > 20 && !isAnimate && child.getVisibility() == View.VISIBLE) {  
  71.                 hide(child);  
  72.             } else if (dy < 20 && !isAnimate && child.getVisibility() == View.INVISIBLE) {  
  73.                 show(child);  
  74.             }  
  75.         }  
  76.     }  
  77.   
  78.     //隱藏時的動畫  
  79.     private void hide(final View view) {  
  80.         ViewPropertyAnimator animator = view.animate().translationY(viewY).setInterpolator(INTERPOLATOR).setDuration(500);  
  81.   
  82.         animator.setListener(new Animator.AnimatorListener() {  
  83.             @Override  
  84.             public void onAnimationStart(Animator animator) {  
  85.                 isAnimate = true;  
  86.             }  
  87.   
  88.             @Override  
  89.             public void onAnimationEnd(Animator animator) {  
  90.                 view.setVisibility(View.INVISIBLE);  
  91.                 isAnimate = false;  
  92.             }  
  93.   
  94.             @Override  
  95.             public void onAnimationCancel(Animator animator) {  
  96.                 show(view);  
  97.             }  
  98.   
  99.             @Override  
  100.             public void onAnimationRepeat(Animator animator) {  
  101.             }  
  102.         });  
  103.         animator.start();  
  104.     }  
  105.   
  106.     //顯示時的動畫  
  107.     private void show(final View view) {  
  108.         ViewPropertyAnimator animator = view.animate().translationY(0).setInterpolator(INTERPOLATOR).setDuration(500);  
  109.         animator.setListener(new Animator.AnimatorListener() {  
  110.             @Override  
  111.             public void onAnimationStart(Animator animator) {  
  112.                 view.setVisibility(View.VISIBLE);  
  113.                 isAnimate = true;  
  114.             }  
  115.   
  116.             @Override  
  117.             public void onAnimationEnd(Animator animator) {  
  118.                 isAnimate = false;  
  119.             }  
  120.   
  121.             @Override  
  122.             public void onAnimationCancel(Animator animator) {  
  123.                 hide(view);  
  124.             }  
  125.   
  126.             @Override  
  127.             public void onAnimationRepeat(Animator animator) {  
  128.             }  
  129.         });  
  130.         animator.start();  
  131.     }  
  132.   
  133. }  

自定義好了Behavior以後就須要在layout佈局文件裏使用了網絡

layout佈局:app

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent">  
  7.   
  8.     <android.support.design.widget.AppBarLayout  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:fitsSystemWindows="true"  
  12.         android:minHeight="?attr/actionBarSize"  
  13.         android:theme="@style/AppTheme.AppBarOverlay">  
  14.   
  15.         <android.support.v7.widget.Toolbar  
  16.             android:id="@+id/activity_dyeOrder_detail_toolbar"  
  17.             android:layout_width="match_parent"  
  18.             android:layout_height="?attr/actionBarSize"  
  19.             android:background="?attr/colorPrimary"  
  20.             android:minHeight="?attr/actionBarSize"  
  21.             app:layout_scrollFlags="scroll|enterAlways"  
  22.             app:navigationIcon="@mipmap/ic_arrow_back_white_24dp"  
  23.             app:popupTheme="@style/AppTheme.PopupOverlay"  
  24.             app:title="@string/dyeOrderDetail" />  
  25.     </android.support.design.widget.AppBarLayout>  
  26.   
  27.   
  28.     <android.support.v4.widget.SwipeRefreshLayout  
  29.         android:id="@+id/swipeRefreshLayout"  
  30.         android:layout_width="match_parent"  
  31.         android:layout_height="match_parent"  
  32.         app:layout_behavior="@string/appbar_scrolling_view_behavior">  
  33.   
  34.         <android.support.v7.widget.RecyclerView  
  35.             android:id="@+id/dyeMessageList"  
  36.             android:layout_width="match_parent"  
  37.             android:layout_height="match_parent"  
  38.             android:descendantFocusability="beforeDescendants"  
  39.             android:scrollbars="vertical"  
  40.             tools:listitem="@layout/recycle_no_dye_message_entry_list" />  
  41.   
  42.     </android.support.v4.widget.SwipeRefreshLayout>  
  43.   
  44.     <LinearLayout  
  45.         android:id="@+id/addLayout"  
  46.         android:layout_width="match_parent"  
  47.         android:layout_height="?attr/actionBarSize"  
  48.         android:gravity="center"  
  49.         android:orientation="horizontal"  
  50.         android:background="@color/white"  
  51.         app:layout_behavior="BottomBarBehavior"  
  52.         app:layout_anchor="@id/swipeRefreshLayout"  
  53.         app:layout_anchorGravity="bottom|end">  
  54.         <TextView  
  55.             android:id="@+id/add"  
  56.             android:layout_width="wrap_content"  
  57.             android:layout_height="wrap_content"  
  58.             android:layout_gravity="center_vertical"  
  59.             android:text="底部菜單" />  
  60.     </LinearLayout>  
  61.   
  62. </android.support.design.widget.CoordinatorLayout>  

須要注意的是app:layout_behavior="BottomBarBehavior"中的BottomBarBehavior若是不在根目錄須要加上包名