Android的Design库---BottomSheetBehavior和BottomSheetDialog

本文介绍了 BottomSheet 的基本使用方法,包括 CoordinatorLayout 和 BottomSheetBehavior 的配置。探讨了 BottomSheet 的不同状态及其回调方法,并提供了使用 BottomSheetDialog 的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BottomSheet 的使用:

BottomSheet 使用需要CoordinatorLayout作为父布局,BottomSheet 的布局作为CoordinatorLayout 的子布局,并且BottomSheetBehavior(比如加上app:layout_behavior=”android.support.design.widget.BottomSheetBehavior”)

实际使用过程中主要依靠BottomSheetBehavior来控制BottomSheet的展示及回调。
BottomSheetBehavior 具有五种状态:

STATE_COLLAPSED: 默认的折叠状态, bottom sheets只在底部显示一部分布局。显示高度可以通过 app:behavior_peekHeight 设置(默认是0)

STATE_DRAGGING : 过渡状态,此时用户正在向上或者向下拖动bottom sheet

STATE_SETTLING: 视图从脱离手指自由滑动到最终停下的这一小段时间

STATE_EXPANDEDbottom sheet 处于完全展开的状态:当bottom 
sheet的高度低于CoordinatorLayout容器时,整个bottom sheet都可见;或者CoordinatorLayout容器已经被bottom sheet填满。

STATE_HIDDEN : 默认无此状态(可通过app:behavior_hideable 启用此状态),启用后用户将能通过向下滑动完全隐藏 bottom sheet

设置状态:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

回调的方法有两个
一个是状态的改变onStateChanged
一个是移动距离的改变onSlide(也就是拖拽的回调)

behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                //这里是bottomSheet 状态的改变,根据slideOffset可以做一些动画  这我们只是简单的设置的放大缩小
                Log.i("cjj", "newState--->" + newState);
                ViewCompat.setScaleX(bottomSheet,1);
                ViewCompat.setScaleY(bottomSheet,1);
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                //这里是拖拽中的回调,根据slideOffset可以做一些动画
                Log.i("cjj", "slideOffset=====》" + slideOffset);
                ViewCompat.setScaleX(bottomSheet,slideOffset);
                ViewCompat.setScaleY(bottomSheet,slideOffset);


            }
        });

这里我们一般都是用于从下面显示的选择框
先用BottomSheetBehavior写
布局

<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/cl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_margin="20dp"
        android:background="#ff0001"
        android:gravity="center"
        android:text=" 点击 or 拖动 我 "
        android:textColor="@android:color/white"/>

    <View
        android:id="@+id/blackview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </View>

    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        app:behavior_hideable="false"
        app:behavior_peekHeight="10dp"
        app:layout_behavior="@string/bottom_sheet_behavior"
        />

</android.support.design.widget.CoordinatorLayout>

代码

package viewpage.yundong.com.bottomsheet;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class RecyclerViewActivity extends AppCompatActivity {
    public RecyclerView recyclerView;
    public BottomSheetBehavior behavior;
    public View blackView;
    private static final String shareStr[] = {
            "微信","QQ","空间","微博","GitHub",
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);

        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
        SimpleStringRecyclerViewAdapter simpleStringRecyclerViewAdapter = new SimpleStringRecyclerViewAdapter(this,shareStr);
        recyclerView.setAdapter(simpleStringRecyclerViewAdapter);



        behavior = BottomSheetBehavior.from(recyclerView);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if(newState == BottomSheetBehavior.STATE_COLLAPSED||newState == BottomSheetBehavior.STATE_HIDDEN){
//                    blackView.setBackgroundColor(Color.TRANSPARENT);
                    blackView.setVisibility(View.GONE);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                // React to dragging events
                blackView.setVisibility(View.VISIBLE);
                ViewCompat.setAlpha(blackView,slideOffset);
            }
        });
        findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });

        blackView = findViewById(R.id.blackview);
        blackView.setBackgroundColor(Color.parseColor("#60000000"));
        blackView.setVisibility(View.GONE);
        blackView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            }
        });
    }
}

适配器我就不写了

然后是大多数会用的BottomSheetDialog
布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_margin="20dp"
        android:background="#ff0001"
        android:gravity="center"
        android:text=" 打开bootom_sheet_dialog "
        android:textColor="@android:color/white"/>
</LinearLayout>

代码

public class BottomSheetDialogActivity extends AppCompatActivity {
    private static final String shareStr[] = {
            "微信","QQ","空间","微博","GitHub","CJJ测试\nRecyclerView自适应","微信朋友圈","短信","推特","遇见"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_sheet_dialog);

        findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showBSDialog();
            }
        });
    }
    private void showBSDialog() {


        final BottomSheetDialog dialog = new BottomSheetDialog(this);
        View contentView = LayoutInflater.from(this).inflate(R.layout.dialog_layout, null);
        RecyclerView recyclerView = (RecyclerView) contentView.findViewById(R.id.bs_rv);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        SimpleStringRecyclerViewAdapter adapter = new SimpleStringRecyclerViewAdapter(this,shareStr);

        recyclerView.setAdapter(adapter);
        dialog.setContentView(contentView);

        View parent = (View) contentView.getParent();
        BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
        contentView.measure(0, 0);
        int height=contentView.getMeasuredHeight();
        Log.e("=====","=="+contentView.getMeasuredHeight()+"==屏幕"+WindowManagerUtils.getWindowHeight(BottomSheetDialogActivity.this));

        if (height>WindowManagerUtils.getWindowHeight(BottomSheetDialogActivity.this)){
            height=WindowManagerUtils.getWindowHeight(BottomSheetDialogActivity.this)-256;
        }
        View view = dialog.getWindow().findViewById(android.support.design.R.id.design_bottom_sheet);
        BottomSheetBehavior.from(view).setPeekHeight(height);
        dialog.getWindow().setGravity(Gravity.BOTTOM);
        dialog.show();

    }


}

这里说下 我设置了显示的高度

首先这个是获取当前dialog布局的高度

View parent = (View) contentView.getParent();
        BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
        contentView.measure(0, 0);
        int height=contentView.getMeasuredHeight();

但是直接 BottomSheetBehavior.from(view).setPeekHeight(height);
会错乱 因为你定的高度超出范围了所以要做判断

这里我比较的是屏幕高度减去它的默认初始高度

  if (height>WindowManagerUtils.getWindowHeight(BottomSheetDialogActivity.this)){
            height=WindowManagerUtils.getWindowHeight(BottomSheetDialogActivity.this)-256;
        }

为什么这么设置显示高度
看看这里吧

WindowManagerUtils我的一个工具类

package viewpage.yundong.com.bottomsheet;

import android.app.Activity;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;

public class WindowManagerUtils {

    /**
     * 把某个view设置成全屏大小
     * 
     * @param context
     * @param view
     */
    public static void toMath(Activity context, View view) {
        DisplayMetrics dm = new DisplayMetrics();
        // 获取屏幕信息
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenWidth = dm.widthPixels;
        int screenHeigh = dm.heightPixels;
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = screenHeigh;
        layoutParams.width = screenWidth;
        view.setLayoutParams(layoutParams);
    }

    /**
     * 获取屏幕的高度
     * @param context
     * @return
     */
    public static int getWindowHeight(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        // 获取屏幕信息
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenHeigh = dm.heightPixels;
        return screenHeigh;
    }

    /**
     * 获取屏幕的宽度
     * @param context
     * @return
     */
    public static int getWindowWidth(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        // 获取屏幕信息
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenWidth = dm.widthPixels;
        return screenWidth;
    }

    /**
     * 返回到点击之前的大小
     * 
     * @param view
     * @param height
     *            之前的高度
     * @param width
     *            之前的宽度
     */
    public static void toReturn(View view, int height, int width) {
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = height;
        layoutParams.width = width;
        view.setLayoutParams(layoutParams);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值