其實上週五的時候已經發過一篇文章。基本實現了底部導航欄隱藏的效果。可是使用起來可能不是很實用。由於以前我實現的方式是繼承了系統的導航欄,而且提供了響應的隱藏顯示方法。這樣就變相等於強制使用這個view,體驗不是很好。因此抽時間把他優化了一下。由於改動比較大,因此從新寫一下他的使用方法,固然做爲改動補償,我會在後半篇文章寫出他的實現方式。php
本文同步自wing的地方酒館android
如今,ByeBuger能夠輕易地將任何view在滑動的時候隱藏或者顯示。同時支持頭部(標題欄)和底部(導航欄)效果。git
各位大佬,以爲還能夠順手給個star,是對我最大的支持,謝謝!
ByeBurger項目地址github
先看一下全新的效果:app
還不錯吧。然而,實現這麼炫酷的效果,僅僅須要一句代碼!maven
1.在gradle 編譯庫文件ide
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享受更多的閱讀空間啦,相信這給用戶帶來了極大的便利。gradle
CoordinatorLayout相似於FrameLayout,因此注意xml層次,TitleBar和BottomTab要在xml下方。
只有實現NestScorll接口View的才能夠實現監聽,例如RecyclerView、NestScrollView.
在ListView下,是不生效的。
以上就是ByeBurger的使用方式,接下來將會介紹ByeBurger的實現方式。若是你只是使用或者不感興趣就不用往下看啦~~不過我仍是建議你看一看,由於知道一個輪子的原理,百利無一害。
在ByeBurger 1.0版本的時候,其實ByeBurger不叫ByeBurger的,而叫作ByeBurgerNavigationView, 由名字能夠看出,他是擴展了系統的BottomNavigationView,但是這樣作有許多弊端,好比強制用戶使用了某個控件,這樣通用性不強。第二,爲了用戶有更多的選擇,加入了頭部隱藏效果。因此說,這個項目已經不能被稱爲NavigationView。因而我將名稱進行了修改。
在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版本。
總體思路就是利用自定義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