前言

最近看到群里有朋友在问类似于

图片

这东西怎么实现

我回答的可能不那么清楚,因为我就答了 bottomSheet,下次我可能会回答的更清楚些

这东西在可能在 flutter 里有如下几种解释

  1. Scaffold 的 bottomSheet 属性
  2. 一个叫 BottomSheet 的 widget 组件
  3. Scaffold.showBottomSheet 方法
  4. showBottomSheet 方法也就是一个底层弹窗

这里分别来简单的说一下

Scaffold 的 bottomSheet 属性

这个就是前言中的那种东西的简单实现方式,直接把聊天的输入框(TextField)放在里面,用 Container 也好,也用其他什么控件也可以,当然 Container => Row => [TextField,Button]就能实现图上的效果了

简单的页面代码如下

import 'package:flutter/material.dart';

class BottomSheet1Page extends StatefulWidget {
  @override
  _BottomSheetPageState createState() => _BottomSheetPageState();
}

class _BottomSheetPageState extends State<BottomSheet1Page> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('bottom sheet'),
      ),
      body: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(index.toString()),
            subtitle: Text("我是${index}的副标题"),
          );
        },
        itemCount: 300,
      ),
      bottomSheet: Container(
        child: Row(
          children: <Widget>[
            Expanded(child: TextField()),
            RaisedButton(
              child: Text('发送'),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}

效果如下

图片 图片

当然如果要适配 iphoneX 之类的 ,底部可能需要套SafeArea在外面,这类的东西不属于本篇 blog 的内容,一笔带过而已

一个叫 BottomSheet 的 widget 组件

这个看了一下内部实现,增加了一些手势,就是支持往下拉关闭BottomSheet

Scaffold.showBottomSheet 方法

import 'package:flutter/material.dart';

class ScaffoldBottomSheetPage extends StatefulWidget {
  @override
  _ScaffoldBottomSheetPageState createState() => _ScaffoldBottomSheetPageState();
}

class _ScaffoldBottomSheetPageState extends State<ScaffoldBottomSheetPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("scaffold show bottom sheet"),
      ),
      body: ListView(),
      floatingActionButton: Builder(builder: (c) {
        return FloatingActionButton(
          onPressed: () {
            Scaffold.of(c).showBottomSheet(
              (c) {
                return Container(
                  child: Text("我是底部弹出来的"),
                  height: 200.0,
                );
              },
            );
          },
        );
      }),
    );
  }
}

使用前的状态

图片

点击后会弹出一个底部弹窗,等待关闭,关闭这个东西你只需要从上往下拖动即可

图片

图片

因为这个是基于 Scaffold 的,所以会和 Scaffold 中的其他部件联动,比如如图所示那个FloatActionButton

showBottomSheet 方法也就是一个底层弹窗

用于从底部弹出弹窗,这个方法是material包中定义的一个全局方法

图片

实际上也是使用的 Scaffold 的 showBottomSheet 方法,直接参考上面就可以

后记

以上