炫酷:一句程式碼實現標題欄、導航欄滑動隱藏,ByeBurger庫的使用和實現

androidwing發表於2016-11-06

其實上週五的時候已經發過一篇文章。基本實現了底部導航欄隱藏的效果。但是使用起來可能不是很實用。因為之前我實現的方式是繼承了系統的導航欄,並且提供了響應的隱藏顯示方法。這樣就變相等於強制使用這個view,體驗不是很好。所以抽時間把他優化了一下。因為改動比較大,所以重新寫一下他的使用方法,當然作為改動補償,我會在後半篇文章寫出他的實現方式。

本文同步自wing的地方酒館

現在,ByeBuger可以輕易地將任何view在滑動的時候隱藏或者顯示。同時支援頭部(標題欄)和底部(導航欄)效果。

各位大佬,覺得還可以順手給個star,是對我最大的支援,謝謝!
ByeBurger專案地址

先看一下全新的效果:

炫酷:一句程式碼實現標題欄、導航欄滑動隱藏,ByeBurger庫的使用和實現

炫酷:一句程式碼實現標題欄、導航欄滑動隱藏,ByeBurger庫的使用和實現

還不錯吧。然而,實現這麼炫酷的效果,僅僅需要一句程式碼!

使用

1.在gradle 編譯庫檔案


allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}


dependencies {
   compile 'com.github.githubwing:ByeBurger:1.1.0'
  compile 'com.android.support:design:25.0.0'
  }複製程式碼

2.你僅僅需要一句程式碼,對,沒錯,只需要在你的View上加入一句。
先使用CoordinatorLayout作為根佈局,然後向你的任何View中插入一句app:layout_behavior屬性,即可實現滑動的隱藏和顯示。
你的標題欄可以是Toolbar或者LinearLayout或者什麼鬼。
同樣你的底部導航欄可以是最新的BottomNavigationView亦或者TabLayout在古老一點的RadioButton都可以!



  
   
        
複製程式碼

具體的一句話是:

 對於標題欄
 app:layout_behavior="@string/bye_burger_title_behavior"複製程式碼
 對於底部導航欄
 app:layout_behavior="@string/bye_burger_bottom_behavior"複製程式碼

之後你就可以讓你的app享受更多的閱讀空間啦,相信這給使用者帶來了極大的便利。

注意

CoordinatorLayout類似於FrameLayout,所以注意xml層次,TitleBar和BottomTab要在xml下方。
只有實現NestScorll介面View的才可以實現監聽,例如RecyclerView、NestScrollView.
在ListView下,是不生效的。

ByeBurger專案地址

以上就是ByeBurger的使用方式,接下來將會介紹ByeBurger的實現方式。如果你只是使用或者不感興趣就不用往下看啦~~不過我還是建議你看一看,因為知道一個輪子的原理,百利無一害。

實現

0.改名原因

在ByeBurger 1.0版本的時候,其實ByeBurger不叫ByeBurger的,而叫做ByeBurgerNavigationView, 由名字可以看出,他是擴充套件了系統的BottomNavigationView,可是這樣做有許多弊端,比如強制使用者使用了某個控制元件,這樣通用性不強。第二,為了使用者有更多的選擇,加入了頭部隱藏效果。所以說,這個專案已經不能被稱為NavigationView。於是我將名稱進行了修改。

1.歷史實現

在1.0版本,我繼承了BottomNavigationView。提供了兩個方法,一個是show,另一個是hide.

 public void show() {

    setY(mStartY);
    TranslateAnimation ta = new TranslateAnimation(0f, 0f,getMeasuredHeight(),0);
    ta.setDuration(300);
    ta.setAnimationListener(this);
    startAnimation(ta);

  }
public void hide() {
    setY(mStartY + getMeasuredHeight());

    TranslateAnimation ta = new TranslateAnimation(0f, 0f, -getMeasuredHeight(), getMeasuredHeight());
    ta.setDuration(300);
    ta.setAnimationListener(this);
    startAnimation(ta);
  }複製程式碼

實際上就是對Y座標進行了一些處理。給個動畫再讓他改變他的Y座標。來達到隱藏效果。(總之隱藏就是讓使用者看不到)

然後利用Behavior,對NestScroll相關滑動進行監聽,來改變ByeBurgerNavigationView的狀態。

public class ByeBurgerBehavior extends CoordinatorLayout.Behavior {複製程式碼

當然,這是1.0的實現,實用性比較低。所以有了1.1.0版本。

2.更新實現

整體思路就是利用自定義behavior去監聽nestScroll的滑動,來讓對應的View改變。之前在CoordinatorLayout 自定義Behavior並不難,由簡到難手把手帶你擼三款! 中介紹過一種Behavior的使用方式,不熟悉的可以先過去看看。這裡用到的是第二種,主要是針對NestScroll進行監聽。

首先,要自定義一個Behavior,他的泛型,也就是child view為View。 這也保證了它的通用性。

public class ByeBurgerBottomBehavior extends CoordinatorLayout.Behavior {}複製程式碼

其次來處理一下onStartNestedScroll()方法,他提供一個返回值,用於過濾掉滑動事件。這裡我們只關心上下滑動。所以應該這樣。

@Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child,
      View directTargetChild, View target, int nestedScrollAxes) {

    return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
  }複製程式碼

最後,在onNestedPreScroll()進行child的對應操作。首先要根據引數dy來判斷上下滑動,然後再根據view當前的狀態來顯示或者隱藏目標View。

public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target,
      int dx, int dy, int[] consumed) {
    //初始化一些引數
    if (isFirstMove) {
      isFirstMove = false;
      mAnimateHelper = AnimateHelper.get(child);
      mAnimateHelper.setStartY(child.getY());
      mAnimateHelper.setMode(AnimateHelper.MODE_BOTTOM);
    }
    if (Math.abs(dy) > mTouchSlop) {
      if (dy < 0) {

        if (mAnimateHelper.getState() == AnimateHelper.STATE_HIDE) {
          mAnimateHelper.show();
        }
      } else if (dy > 0) {
        if (mAnimateHelper.getState() == AnimateHelper.STATE_SHOW) {
          mAnimateHelper.hide();
        }
      }
    }
  }
}複製程式碼

在上面函式裡,view的隱藏和顯示委託給了AnimateHelper類。這是一個Helper,用來管理View的狀態,也就是託付View隱藏或者顯示。他的程式碼很簡單,如下:

public class AnimateHelper {
  public View mTarget;
  public float mStartY;
  public static int STATE_SHOW = 1;
  public static int STATE_HIDE = 0;
  public int mCurrentState = STATE_SHOW;
  public int mMode = MODE_TITLE;
  public static int MODE_TITLE = 233;
  public static int MODE_BOTTOM = 2333;
}複製程式碼

提供一些成員,用於儲存 狀態,模式,起始Y座標等等。

提供一個工廠方法,用於獲得處理目標view的helper:

 public static AnimateHelper get(View target) {
    return new AnimateHelper(target);
  }複製程式碼

之後,提供show方法和hide方法,用於執行view的隱藏或者顯示:

public void show() {
    if (mMode == MODE_TITLE) {
      showTitle();
    } else if (mMode == MODE_BOTTOM) {
      showBottom();
    }
  }

 public void hide() {
    if (mMode == MODE_TITLE) {
      hideTitle();
    } else if (mMode == MODE_BOTTOM) {
      hideBottom();
    }
  }複製程式碼

而 showTitle()和 showBottom()之類的如1.0版一樣,是改變了一下y座標,然後執行動畫。

如何讓使用者使用

這裡參考了系統預留behavior的使用方式,由於Behavior例項是系統反射出來的,所以需要完整的包名。於是我就將Beavior的包名寫在了string.xml裡,如下:

  com.wingsofts.byeburgernavigationview.ByeBurgerBottomBehavior
  com.wingsofts.byeburgernavigationview.ByeBurgerTitleBehavior複製程式碼

所以使用者使用起來及其簡便,只需要在xml中給view加入一行程式碼app:layoutbehavior="@string/byeburgerbottom_behavior"即可。

以上,ByeBurger庫的使用和實現就寫完了。終於有機會回饋開源社群了,我感到很開心,哇咔咔。

如果你覺得還不錯 歡迎star, 更歡迎貢獻程式碼。

本庫下載地址:github.com/githubwing/…

歡迎加入我的android群:425983695

相關文章