【Android】BottomSheetDialog详解

来源:互联网 发布:关闭miui优化有影响吗 编辑:程序博客网 时间:2024/06/06 01:10

1.简介

BottomSheetDialog是一个自定义的从底部滑入的对话框。市面上很多App都有类似的效果,今天我们实现如下效果:

这里写图片描述

2.页面布局

从底部弹出view的效果是BottomSheetBehavior来实现的。view必须支持嵌套滚动,而且必须是CoordinatorLayout的直接子类,来看下主题布局。

<?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:id="@+id/activity_bottom_sheet"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    app:behavior_hideable="true"    >    <!--Toolbar-->    <android.support.design.widget.AppBarLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:theme="@style/ThemeOverlay.AppCompat.Light">        <android.support.v7.widget.Toolbar            android:id="@+id/toolbar"            android:layout_width="match_parent"            android:layout_height="?attr/actionBarSize"            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />    </android.support.design.widget.AppBarLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@+id/tab_layout"        android:gravity="center"        android:orientation="vertical"        app:behavior_hideable="true"        app:layout_behavior="@string/appbar_scrolling_view_behavior"        >        <Button            android:text="显示"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginTop="20dp"            android:id="@+id/btn_show"            />        <Button            android:text="底部按钮"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginTop="20dp"            android:id="@+id/btn_bottom" />    </LinearLayout>    <!--底部弹出框-->    <LinearLayout        android:id="@+id/tab_layout"        android:layout_width="match_parent"        android:layout_height="?actionBarSize"        android:layout_alignParentBottom="true"        android:background="@android:color/holo_purple"        app:behavior_hideable="true"        app:behavior_peekHeight="0dp"        app:layout_behavior="@string/bottom_sheet_behavior">        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="首页" />        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="课程" />        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="我的" />    </LinearLayout></android.support.design.widget.CoordinatorLayout>

3.点击按钮弹出BottomSheetDialog

创建BottomSheetDialog以及相关的初始化:

        WindowManager wm = this.getWindowManager();        int height = wm.getDefaultDisplay().getHeight();        //构造函数的第二个参数可以设置BottomSheetDialog的主题样式//        mBottomSheetDialog = new BottomSheetDialog(this,R.style.MyBottomDialog);        mBottomSheetDialog = new BottomSheetDialog(this);        //导入底部reycler布局        View view = LayoutInflater.from(this).inflate(R.layout.recycler_view, null, false);        mBottomSheetDialog.setContentView(view);        BottomSheetBehavior mBehavior = BottomSheetBehavior.from((View) view.getParent());        //设置默认弹出高度为屏幕的0.4倍        mBehavior.setPeekHeight((int) (0.4 * height));        //设置点击dialog外部不消失        mBottomSheetDialog.setCanceledOnTouchOutside(false);        //RecyclerView相关设置        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);        recyclerView.setLayoutManager(new LinearLayoutManager(this));        recyclerView.setAdapter(new MyRecyclerAdapter(this));

点击按钮后,控制显示和隐藏:

if (!mBottomSheetDialog.isShowing()) {     mBottomSheetDialog.show();} else {     mBottomSheetDialog.dismiss();}

此时点击按钮,如下效果:

这里写图片描述

问题:此时再次点击显示按钮的话,不会弹出底部框,屏幕会变暗,这是之前我们划下收缩隐藏BottomSheetDialog后,bottomSheetDialogBehavior的状态为隐藏,再次show之后,系统未恢复bottomSheetDialogBehavior的状态,还是隐藏,所以再次点击后页面只是变暗,可以在隐藏时通过设置BottomSheetDialog的状态来解决:

final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view);bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

4.弹出普通的View

我们点击显示底部按钮时弹出如下界面:

这里写图片描述

看下布局文件,CoordinatorLayout里放了一个LinearLayout:

<?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:id="@+id/activity_bottom_sheet"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:fitsSystemWindows="true"    app:behavior_hideable="true"    >    <!--底部弹出框-->    <LinearLayout        android:id="@+id/tab_layout"        android:layout_width="match_parent"        android:layout_height="?actionBarSize"        android:layout_alignParentBottom="true"        android:background="@android:color/holo_purple"        app:behavior_hideable="true"        app:behavior_peekHeight="0dp"        app:layout_behavior="@string/bottom_sheet_behavior">        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="首页" />        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="课程" />        <Button            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:text="我的" />    </LinearLayout></android.support.design.widget.CoordinatorLayout>

通过设置LinearLayout的app:layout_behavior属性来设置此布局的行为,设置后Linear会在屏幕的底部:

app:layout_behavior="@string/bottom_sheet_behavior"

控制显示和隐藏:

// 拿到这个tab_layout对应的BottomSheetBehaviormBottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.tab_layout));// 控制展开还是关闭if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);} else if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);}

5.解决弹出dialog后Android5.0+status bar变黑

自定义BottomSheetDialog,屏幕高度减去状态栏的高度即可:

public class MyBottomSheetDialog extends BottomSheetDialog{    private Activity activity;    public MyBottomSheetDialog(@NonNull Context context,Activity activity) {        super(context);        this.activity = activity;    }    public MyBottomSheetDialog(@NonNull Context context, @StyleRes int theme,Activity activity) {        super(context, theme);        this.activity = activity;    }    protected MyBottomSheetDialog(@NonNull Context context, boolean cancelable, OnCancelListener cancelListener,Activity activity) {        super(context, cancelable, cancelListener);        this.activity = activity;    }    @Override    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;    }}

参考:

1.http://blog.csdn.net/maosidiaoxian/article/details/52288597

2.http://blog.csdn.net/yanzhenjie1003/article/details/51938425


源码下载

0 0