基于HiOverlay实现弹幕输入界面

封装弹幕输入Widget

barrage_input.dart

/// 弹幕输入界面
class BarrageInput extends StatelessWidget {
  // 输入界面关闭回调
  final VoidCallback onTabClose;

  BarrageInput({Key key, @required this.onTabClose}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    TextEditingController editingController = TextEditingController();

    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Column(
        children: [
          // 空白区域点击关闭弹框
          Expanded(
              child: GestureDetector(
            onTap: () {
              if (onTabClose != null) onTabClose();
              Navigator.of(context).pop();
            },
            child: Container(
              color: Colors.transparent,
            ),
          )),
          // 适配 IOS 刘海屏
          SafeArea(
              child: Container(
            color: Colors.white,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                _buildInput(editingController, context),
                _buildSendBtn(editingController, context)
              ],
            ),
          )),
        ],
      ),
    );
  }

  /// 输入框组件
  _buildInput(TextEditingController editingController, BuildContext context) {
    return Expanded(
        child: Container(
      margin: EdgeInsets.only(top: 10, bottom: 10),
      decoration: BoxDecoration(
        color: Colors.grey[200],
        borderRadius: BorderRadius.circular(15),
      ),
      child: TextField(
        // 自动获取焦点
        autofocus: true,
        controller: editingController,
        onSubmitted: (value) {
          _send(value, context);
        },
        // 光标颜色
        cursorColor: primary,
        decoration: InputDecoration(
            isDense: true,
            // 内边距
            contentPadding:
                EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
            // 取消输入框边框
            border: InputBorder.none,
            // 提示文本样式
            hintStyle: TextStyle(fontSize: 13, color: Colors.grey),
            hintText: '发个友善的弹幕见证当下'),
      ),
    ));
  }

  /// 发送弹幕
  void _send(String text, BuildContext context) {
    if (text.isNotEmpty) {
      // 关闭弹出框
      if (onTabClose != null) onTabClose();
      // 返回上一页面,并传递输入内容
      Navigator.pop(context, text);
    }
  }

  /// 发送按钮
  _buildSendBtn(TextEditingController editingController, BuildContext context) {
    return InkWell(
      onTap: () {
        // 获取输入框内容
        var text = editingController.text?.trim() ?? "";
        // 发送弹幕
        _send(text, context);
      },
      child: Container(
        padding: EdgeInsets.all(10),
        child: Icon(Icons.send_rounded, color: Colors.grey),
      ),
    );
  }
}

实现弹幕输入

pubspec.yaml

引入弹出框插件

flutter_overlay: ^0.0.2

video_detail_page.dart

实现弹幕输入展开关闭

 /// 发送弹幕按钮,点击按钮弹出发送弹幕界面
  _buildBarrageBtn() {
    return BarrageSwitch(
        inputShowing: _inputShowing,
        // 输入框切换回调
        onShowInput: () {
          setState(() {
            _inputShowing = true;
          });
          // 显示输入弹出框
          HiOverlay.show(context, child: BarrageInput(onTabClose: () {
            setState(() {
              _inputShowing = false;
            });
          })).then((value) {
            // _barrageKey.currentState 获取到的事弹幕组件
            _barrageKey.currentState.send(value);
          });
        },
        // 展开与收缩回调
        onBarrageSwitch: (open) {
          if (open) {
            // 播放弹幕
            _barrageKey.currentState.play();
          } else {
            // 暂停弹幕
            _barrageKey.currentState.pause();
          }
        });
  }

封装输入状态切换Widget

barrage_switch.dart

封装弹幕发送按钮的切换状态

class BarrageSwitch extends StatefulWidget {
  /// 初始时是否展开
  final bool initSwitch;

  /// 是否输入中
  final bool inputShowing;

  /// 输入框切换回调
  final VoidCallback onShowInput;

  /// 展开与收缩状态切换回调
  final ValueChanged<bool> onBarrageSwitch;

  const BarrageSwitch(
      {Key key,
      this.initSwitch = true,
      this.inputShowing = false,
      @required this.onShowInput,
      @required this.onBarrageSwitch})
      : super(key: key);

  @override
  _BarrageSwitchState createState() => _BarrageSwitchState();
}

class _BarrageSwitchState extends State<BarrageSwitch> {
  bool _barrageSwitch;

  @override
  void initState() {
    super.initState();
    _barrageSwitch = widget.initSwitch;
  }

  /// 文本
  _buildText() {
    var text = _barrageSwitch ? '弹幕输入中' : '点我发送弹幕';
    return _barrageSwitch
        ? InkWell(
            onTap: () {
              // 显示弹幕输入框
              widget.onShowInput();
            },
            child: Padding(
                padding: EdgeInsets.only(right: 10),
                child: Text(text,
                    style: TextStyle(fontSize: 12, color: Colors.grey))),
          )
        : Container();
  }

  /// 图标
  _buildIcon() {
    return InkWell(
      onTap: () {
        setState(() {
          _barrageSwitch = !_barrageSwitch;
        });
        widget.onBarrageSwitch(_barrageSwitch);
      },
      child: Icon(Icons.live_tv_rounded,
          color: _barrageSwitch ? primary : Colors.grey),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 28,
      padding: EdgeInsets.only(left: 10, right: 10),
      margin: EdgeInsets.only(right: 15),
      alignment: Alignment.center,
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey[300]),
        borderRadius: BorderRadius.circular(15),
      ),
      child: Row(
        children: [_buildText(), _buildIcon()],
      ),
    );
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值