1. 程式人生 > >BottomSheet 的詳解及注意事項

BottomSheet 的詳解及注意事項

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;
    }
}