AndroidBottomSheetDialog详解
Posted 寒小枫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AndroidBottomSheetDialog详解相关的知识,希望对你有一定的参考价值。
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对应的BottomSheetBehavior
mBottomSheetBehavior = 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
以上是关于AndroidBottomSheetDialog详解的主要内容,如果未能解决你的问题,请参考以下文章