Flutter 之 BottomSheet (五十八)
2024-04-09 22:30:13  阅读数 1417

1. BottomSheet

BottomSheet 作为组件直接使用的时候比较少,比如配合 Scaffold 的子属性使用,可以理解为展示在屏幕下方的一个组件。

BottomSheet 定义

  const BottomSheet({
    Key? key,
    this.animationController,
    this.enableDrag = true,
    this.onDragStart,
    this.onDragEnd,
    this.backgroundColor,
    this.elevation,
    this.shape,
    this.clipBehavior,
    this.constraints,
    required this.onClosing,
    required this.builder,
  })

1.1 属性介绍

BottomSheet 属性 介绍
animationController 动画控制器
enableDrag 是否可以拖动,默认为 true
onDragStart 开始拖拽回调,没有找到具体使用场景,后续更新
onDragEnd 结束拖拽回调,没有找到具体使用场景,后续更新
backgroundColor 背景色
elevation 阴影高度
shape 形状 BorderShape
clipBehavior 剪切方式
constraints BoxConstraints 约束
onClosing 关闭回调函数
builder 构建函数

1.2 示例


class MSBottomSheetDemo1 extends StatelessWidget {
  const MSBottomSheetDemo1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("bottomSheet")),
      body: Center(
        child: Text("BottomSheetDemo"),
      ),
      bottomSheet: BottomSheet(
        enableDrag: false, //是否可以拖动,默认为 true
        onClosing: () {},
        builder: (ctx) {
          return Container(
            color: Colors.cyan,
            height: 200,
            alignment: Alignment.center,
            child: Text("bottomSheet in Scaffold"),
          );
        },
      ),
    );
  }
}

image.png

2. showModalBottomSheet

showModalBottomSheet 是一个直接调起 BottomSheet 的 api,使用频率较高。


class MSBottomSheetDemo2 extends StatelessWidget {
  const MSBottomSheetDemo2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("BottomSheetDemo")),
      body: Center(
        child: Text("Demo"),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.pets),
        onPressed: () {
          showModalBottomSheet(
            context: context,
            builder: (ctx) {
              return Container(
                height: 100,
                child: Text("Bottom Sheet"),
              );
            },
          );
        },
      ),
    );
  }
}

80.gif

示例2


class MSBottomSheetDemo4 extends StatelessWidget {
  const MSBottomSheetDemo4({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("BottomSheetDemo")),
      body: Center(
        child: Text("Demo"),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.pets),
        onPressed: () {
          showModalBottomSheet(
            context: context,
            builder: (ctx) {
              return Container(
                height: 100,
                child: Column(
                  children: [
                    TextButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("保存"),
                    ),
                    TextButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("取消"),
                    ),
                  ],
                ),
              );
            },
          );
        },
      ),
    );
  }
}

82.gif

收起上拉框

Navigator.pop(context);

3. showBottomSheet

showBottomSheet 对新手可能不太友好,它的实际调用是 Scaffold.of(context).showBottomSheet,.of(context) 方法在当前同一层级是拿不到 Scaffold Widget 的,所以会报错。需要在封装一层 class 进行使用 或者 使用Builder


class MSBottomSheetDemo3 extends StatelessWidget {
  MSBottomSheetDemo3({Key? key}) : super(key: key);

  var _isShow = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("BottomSheetDemo")),
      body: Center(
        child: Text("Hello World"),
      ),
      floatingActionButton: _buildFloatingActionButton(),
    );
  }

  Widget _buildFloatingActionButton() {
    return Builder(
      builder: (context) {
        return FloatingActionButton(
          child: Icon(
            Icons.pets,
          ),
          onPressed: () {
            _floatingActionButtonEvent(context);
            _isShow = !_isShow;
          },
        );
      },
    );
  }

  _floatingActionButtonEvent(BuildContext context) {
    if (_isShow) {
      Navigator.of(context).pop();
    } else {
      _showSheet(context);
    }
  }

  void _showSheet(BuildContext context) {
    showBottomSheet(
      context: context,
      builder: (ctx) {
        return Container(
          width: double.infinity,
          height: 200,
          color: Colors.cyan,
          alignment: Alignment.center,
          child: Text("BottomSheet"),
        );
      },
    );
  }
}

81.gif

收起上拉框

Navigator.pop(context);

https://www.jianshu.com/p/72a999bfc09f