BottomSheet 的詳解及注意事項
阿新 • • 發佈:2019-01-27
android support library更新的比較快,使用了幾個控制元件挺不錯,不過今天只寫BottomSheet 。
OK,這個東西肯定很多人都沒聽過和用過,其實用起來特別方便和簡單,不過它的使用需要引入Behavior機制,別說你沒聽說過Behavior,Behavior是CoordinatorLayout的核心內容,其允許我們在自定義控制元件的前提下實現一些特效,BottomSheet 就是通過Behavior實現的。
下面看佈局:
<?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:background="@color/white"
android:fitsSystemWindows ="true"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="點選一下彈出" />
<android.support.v4.widget.NestedScrollView
android:id="@+id/scoll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="這是BottomSheet "
android:textColor="@color/white" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
佈局很簡單,只需要在NestedScrollView中指定Behavior就可以了,看一下程式碼,幾行程式碼搞定,幾行程式碼而已,當然也可以不用程式碼,但是使用者怎麼知道你會從下面彈出來呢是不是。
BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.scoll));
if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else {
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
如果是展開的狀態,就關閉,很簡單,效果圖,點選按鈕從下方彈出。
其實這個我們用的並不多,個人覺得比較實用的還是BottomSheetDialog,下面來看一下效果
為了方便直接把兩張圖放一起了,下方的列表如果顯示不完,可以上拉鋪滿螢幕,效果槓槓的,當然,如果用過的朋友肯定遇到彈出時狀態列變黑的問題,下面再說,我們來看看這個效果的程式碼,很簡單的,
BottomSheetAdapter adapter = new BottomSheetAdapter(this);
RecyclerView recyclerView = (RecyclerView) LayoutInflater.from(this).inflate(R.layout.recycler, null);
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT);
recyclerView.setLayoutParams(params);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapter);
final MyBottomSheetDialog dialog = new MyBottomSheetDialog(this, this);
dialog.setContentView(recyclerView);
dialog.show();
直接載入一個recycleView佈局,這裡adapter就省略了,注意,這裡我是用了自定義的MyBottomSheetDialog,上面說到了彈出會使狀態列變黑的問題在自定義中解決,看了一下原始碼,不能改變狀態列的顏色是因為 OnCreate()裡面setLayout()中的引數設定成了MatchParent,我們需要自定義重寫,直接貼程式碼:
/**
* 當dialog彈出時,會把狀態列的顏色變為黑色,需重寫onCreate(),在裡面進行高度設定
* <p/>
*
* Created by dong.he on 2016/9/6.
*/
public class MyBottomSheetDialog extends BottomSheetDialog {
private Context mContext;
Activity activity;
public MyBottomSheetDialog(@NonNull Context context,Activity activity) {
super(context);
mContext = context;
this.activity = activity;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int screenHeight = getScreenHeight(activity);
int statusBarHeight = getStatusBarHeight(getContext());
int dialogHeight = screenHeight - statusBarHeight;
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight == 0 ? ViewGroup.LayoutParams.MATCH_PARENT : dialogHeight);
}
private static int getScreenHeight(Activity activity) {
DisplayMetrics displaymetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
return displaymetrics.heightPixels;
}
private static int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
Resources res = context.getResources();
int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = res.getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
}