封装弹幕输入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()],
),
);
}
}