介紹
用于CoordiantorLayout的子View的交互行為插件。一個(gè)Behavior實(shí)現(xiàn)了用戶的一個(gè)或者多個(gè)交互行為,包括拖拽、滑動(dòng)行您、快滑或者其他一些手勢(shì)
/**
* 表示是否給應(yīng)用了Behavior 的View 指定一個(gè)依賴的布局,通常剪廉,當(dāng)依賴的View 布局發(fā)生變化時(shí)
* 不管被被依賴View 的順序怎樣娃循,被依賴的View也會(huì)重新布局
* @param parent
* @param child 綁定behavior 的View
* @param dependency 依賴的view
* @return 如果child 是依賴的指定的View 返回true,否則返回false
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency);
}
/**
* 當(dāng)被依賴的View 狀態(tài)(如:位置、大卸方)發(fā)生變化時(shí)捌斧,這個(gè)方法被調(diào)用
* @param parent
* @param child
* @param dependency
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
return super.onDependentViewChanged(parent, child, dependency);
}
/**
* 當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動(dòng)的時(shí)候被調(diào)用。當(dāng)返回值為true的時(shí)候表明
* coordinatorLayout 充當(dāng)nested scroll parent 處理這次滑動(dòng)泉沾,需要注意的是只有當(dāng)返回值為true
* 的時(shí)候捞蚂,Behavior 才能收到后面的一些nested scroll 事件回調(diào)(如:onNestedPreScroll、onNestedScroll等)
* 這個(gè)方法有個(gè)重要的參數(shù)nestedScrollAxes跷究,表明處理的滑動(dòng)的方向姓迅。
*
* @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
* @param child 和Behavior 綁定的View
* @param directTargetChild
* @param target
* @param nestedScrollAxes 嵌套滑動(dòng) 應(yīng)用的滑動(dòng)方向,看 {@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
* {@link ViewCompat#SCROLL_AXIS_VERTICAL}
* @return
*/
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 嵌套滾動(dòng)發(fā)生之前被調(diào)用
* 在nested scroll child 消費(fèi)掉自己的滾動(dòng)距離之前俊马,嵌套滾動(dòng)每次被nested scroll child
* 更新都會(huì)調(diào)用onNestedPreScroll丁存。注意有個(gè)重要的參數(shù)consumed,可以修改這個(gè)數(shù)組表示你消費(fèi)
* 了多少距離潭袱。假設(shè)用戶滑動(dòng)了100px,child 做了90px 的位移柱嫌,你需要把 consumed[1]的值改成90,
* 這樣coordinatorLayout就能知道只處理剩下的10px的滾動(dòng)屯换。
* @param coordinatorLayout
* @param child
* @param target
* @param dx 用戶水平方向的滾動(dòng)距離
* @param dy 用戶豎直方向的滾動(dòng)距離
* @param consumed
*/
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
/**
* 進(jìn)行嵌套滾動(dòng)時(shí)被調(diào)用
* @param coordinatorLayout
* @param child
* @param target
* @param dxConsumed target 已經(jīng)消費(fèi)的x方向的距離
* @param dyConsumed target 已經(jīng)消費(fèi)的y方向的距離
* @param dxUnconsumed x 方向剩下的滾動(dòng)距離
* @param dyUnconsumed y 方向剩下的滾動(dòng)距離
*/
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
/**
* 嵌套滾動(dòng)結(jié)束時(shí)被調(diào)用编丘,這是一個(gè)清除滾動(dòng)狀態(tài)等的好時(shí)機(jī)。
* @param coordinatorLayout
* @param child
* @param target
*/
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
}
/**
* onStartNestedScroll返回true才會(huì)觸發(fā)這個(gè)方法彤悔,接受滾動(dòng)處理后回調(diào)嘉抓,可以在這個(gè)
* 方法里做一些準(zhǔn)備工作,如一些狀態(tài)的重置等晕窑。
* @param coordinatorLayout
* @param child
* @param directTargetChild
* @param target
* @param nestedScrollAxes
*/
@Override
public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 用戶松開手指并且會(huì)發(fā)生慣性動(dòng)作之前調(diào)用抑片,參數(shù)提供了速度信息,可以根據(jù)這些速度信息
* 決定最終狀態(tài)杨赤,比如滾動(dòng)Header敞斋,是讓Header處于展開狀態(tài)還是折疊狀態(tài)。返回true 表
* 示消費(fèi)了fling.
*
* @param coordinatorLayout
* @param child
* @param target
* @param velocityX x 方向的速度
* @param velocityY y 方向的速度
* @return
*/
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
//可以重寫這個(gè)方法對(duì)子View 進(jìn)行重新布局
@Override
public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
return super.onLayoutChild(parent, child, layoutDirection);
}
BottomSheetBehavior/BottomSheetDialog的使用
BottomSheetBehavior 實(shí)現(xiàn)的效果在我們的項(xiàng)目中用的比較多疾牲,它就是從底部彈出一個(gè)布局植捎,在很多的應(yīng)用中,分享功能都有這樣一個(gè)交互阳柔。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/btn_show_bottom_sheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="顯示/隱藏 BottomSheet"
android:background="@android:color/darker_gray"
android:textColor="@color/black"
android:padding="10dp"
/>
<FrameLayout
android:id="@+id/share_view"
app:layout_behavior="@string/bottom_sheet_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical"
app:behavior_peekHeight="0dp"
>
<include layout="@layout/bottom_sheet_share_dialog"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
注意上面這行代碼: app:behavior_peekHeight="0dp"焰枢,peekHeight 屬性是設(shè)置bottomSheet 折疊時(shí)的高度,我們?cè)O(shè)置為0表示折疊的時(shí)候完全隱藏,默認(rèn)情況時(shí)顯示布局的高度济锄,布局會(huì)顯示在界面暑椰,所以,如果要一開始布局不顯示在界面上的話荐绝,需要將peekHeight 設(shè)置為0一汽。也可以在代碼中設(shè)置, 通過sheetBehavior.setPeekHeight(0)很泊。
- 共有五種狀態(tài)
1, STATE_EXPANDED 展開狀態(tài)角虫,顯示完整布局。
2委造,STATE_COLLAPSED 折疊狀態(tài)戳鹅,顯示peekHeigth 的高度,如果peekHeight為0昏兆,則全部隱藏,與STATE_HIDDEN效果一樣枫虏。
3,STATE_DRAGGING 拖拽時(shí)的狀態(tài)
4爬虱,STATE_HIDDEN 隱藏時(shí)的狀態(tài)
5隶债,STATE_SETTLING 釋放時(shí)的狀態(tài)
View shareView = findViewById(R.id.share_view);
//獲取BottomSheetBehavior
final BottomSheetBehavior sheetBehavior = BottomSheetBehavior.from(shareView);
//設(shè)置折疊時(shí)的高度
//sheetBehavior.setPeekHeight(BottomSheetBehavior.PEEK_HEIGHT_AUTO);
//監(jiān)聽BottomSheetBehavior 狀態(tài)的變化
sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
//下滑的時(shí)候是否可以隱藏
sheetBehavior.setHideable(true);
findViewById(R.id.btn_show_bottom_sheet).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(sheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED){
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}else {
sheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
}
});
BottomSheetDialog
從底部彈出一個(gè)Dialog。BottomSheetDialog使用起來更加方便跑筝。
將Dialog顯示的布局添加到綁定了BottomSheetBehavior的ViewGroup里死讹。這個(gè)方法在setContent()方法里被調(diào)用。
- 創(chuàng)建歌單以及BottomSheetDialog的方法如下
private void showBottomSheetDialog(){
BottomSheetDialog dialog = new BottomSheetDialog(this);
View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_dialog,null);
handleList(view);
dialog.setContentView(view);
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
}
private void handleList(View contentView){
RecyclerView recyclerView = (RecyclerView) contentView.findViewById(R.id.recyclerView);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
MusicAdapter adapter = new MusicAdapter();
recyclerView.setAdapter(adapter);
adapter.setData(mockData());
adapter.notifyDataSetChanged();
}
這里寫一個(gè)解決下滑影藏dialog后曲梗,再次調(diào)用show方法顯示時(shí)赞警,不能彈出Dialog。
一定要在dismiss后重新設(shè)置Behavior的狀態(tài)
/**
* share Dialog
*/
private void showShareDialog(){
if(mBottomSheetDialog == null){
mBottomSheetDialog = new BottomSheetDialog(this);
View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_share_dialog,null);
mBottomSheetDialog.setContentView(view);
mBottomSheetDialog.setCancelable(true);
mBottomSheetDialog.setCanceledOnTouchOutside(true);
// 解決下滑隱藏dialog 后虏两,再次調(diào)用show 方法顯示時(shí)愧旦,不能彈出Dialog
View view1 = mBottomSheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view1);
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
Log.i("BottomSheet","onStateChanged");
mBottomSheetDialog.dismiss();
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}else{
mBottomSheetDialog.show();
}
這是別人寫的Behavior的一些列子,供大家參考
https://github.com/pinguo-zhouwei/MaterialDesignSamples