轉載自:http://blog.csdn.net/qibin0506/article/details/51002241
最近Android更新了support library, 版本到了23.2, 從官方blog中我們還是可以看到幾個令人心動的特性的,例如夜間模式的支持,BottomSheet.今天我們就來介紹一下這個Bottom Sheet,這可能會給我們開發中需要的一些效果帶來便利.
雖然這裏我們準備用整整一篇博客的時間來介紹它,不過這東西使用起來太簡單了也太方便了,這還要感謝Behavior機制的引入,我記得在博客源碼看CoordinatorLayout.Behavior原理中說過,Behavior其實是CoordinatorLayout
的核心內容,Behavior允許我們在不用自定義控件的前提下實現一些效果,Bottom Sheet正是通過Behavior實現的.
首先我們來看一個效果,
這個效果的實現很簡單,甚至基本不需要Java代碼,我們只需要給我們的下面的這個可滑動的view一個behavior就ok,把這個behavior指定爲android.support.design.widget.BottomSheetBehavior
就可以達到這種效果了,是不是很簡單?
來看看代碼吧,
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="org.loader.bottomsheetmodule.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content">
<Button
android:layout_gravity="center_horizontal"
android:onClick="intro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="介紹"/>
<Button
android:layout_gravity="center_horizontal"
android:onClick="select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="選擇"/>
</LinearLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:background="@color/colorPrimary"
android:text="人不會死在絕境,卻往往栽在十字路口"
android:textColor="@android:color/white"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
看到NestedScrollView
的behavior了嗎? 我們僅僅指定了一下他的值就可以了,其他的地方沒有任何特殊的.
雖然說我們不需要任何java代碼就可以實現,不過這裏我們還是希望可以通過按鈕去控制它,從底部滑出畢竟太隱藏了,沒有幾個人可以猜到.
public void intro(View view) {
BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.scroll));
if(behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}else {
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
代碼也很簡單,首先我們從NestedScrollView
上獲取到他的Behavior,因爲我們知道是 BottomSheetBehavior
,所以這裏直接死用BottomSheetBehavior.from
方法來獲取,然後通過getState
方法來判斷現在的狀態,如果是展開的狀態,我們就讓它收縮起來,反之,展開它.
我們還可以給BottomSheetBehavior
一個callback來監聽狀態,
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
這個確實簡單,不過有沒有發現它的用戶不是那麼的廣,接下來我們就要來介紹一個用戶相對來說廣泛點的BottomSheetDialog
,這個Dialog可以實現什麼效果呢? 舉個例子吧,現在我們在商城相關的app,當我們點擊購買的時候需要選擇一下要購買的商品的屬性,以前我們可能是在底部彈出一個Popupwindow
來實現,現在好了,我們可以利用BottomSheetDialog
輕鬆的實現這個功能了.首先繼續來看看效果吧.
這裏是一個含有一個List的dialog,當我們點擊按鈕顯示的時候,它會出現一部分,當我們拖動它的時候,他會佔滿屏幕,現在我們就來看一下代碼如何實現,
public void select(View view) {
RecyclerView recyclerView = (RecyclerView) LayoutInflater.from(this)
.inflate(R.layout.list, null);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
Adapter adapter = new Adapter();
recyclerView.setAdapter(adapter);
final BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(recyclerView);
dialog.show();
adapter.setOnItemClickListener(new Adapter.OnItemClickListener() {
@Override
public void onItemClick(int position, String text) {
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
}
static class Adapter extends RecyclerView.Adapter<Adapter.Holder> {
private OnItemClickListener mItemClickListener;
public void setOnItemClickListener(OnItemClickListener li) {
mItemClickListener = li;
}
@Override
public Adapter.Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(item);
}
@Override
public void onBindViewHolder(final Adapter.Holder holder, int position) {
holder.tv.setText("item " + position);
if(mItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mItemClickListener.onItemClick(holder.getLayoutPosition(),
holder.tv.getText().toString());
}
});
}
}
@Override
public int getItemCount() {
return 50;
}
class Holder extends RecyclerView.ViewHolder {
TextView tv;
public Holder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.text);
}
}
interface OnItemClickListener {
void onItemClick(int position, String text);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
別看代碼長,主要是Adapter的代碼!而且沒有任何難度!我們來看select方法,這個方法中我們通過LayoutInflater
加載了一個佈局,這個佈局很簡單,就是一個RecyclerView
.接下來的幾行代碼是配置RecyclerView
和它的Adapter
,相信不用多說大家也已經很熟悉了.關鍵是繼續往下的3行代碼,首先我們new了一個BottomSheetDialog
,然後通過setContentView
方法把我們inflate進來的佈局設置到這個dialog上,最後調用dialog的show方法將dialog顯示出來,這個效果就是這麼容易就實現了,這個dialog特性的代碼我們一行也沒有寫,android都已經幫我們完成好了.最後我們還在item的click事件中將這個dialog隱藏掉了.
好了,今天這篇博客很簡單,主要是最新的support包中這個bottomSheet
的使用,以後大家在項目中又可以多一種實現dialog的方式了, 趕緊嘗試一下吧.