其實上週五的時候已經發過一篇文章。基本實現了底部導航欄隱藏的效果。但是使用起來可能不是很實用。因為之前我實現的方式是繼承了系統的導航欄,並且提供了響應的隱藏顯示方法。這樣就變相等於強制使用這個view,體驗不是很好。所以抽時間把他優化了一下。因為改動比較大,所以重新寫一下他的使用方法,當然作為改動補償,我會在後半篇文章寫出他的實現方式。
本文同步自wing的地方酒館
現在,ByeBuger可以輕易地將任何view在滑動的時候隱藏或者顯示。同時支援頭部(標題欄)和底部(導航欄)效果。
各位大佬,覺得還可以順手給個star,是對我最大的支援,謝謝!
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的實現方式。如果你只是使用或者不感興趣就不用往下看啦~~不過我還是建議你看一看,因為知道一個輪子的原理,百利無一害。
實現
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