flutter聊天app應(yīng)用實(shí)例|flutter聊天界面

FlutterChat聊天室項(xiàng)目是基于flutter+dart+video_player+photo_view+image_picker等技術(shù)實(shí)現(xiàn)的跨平臺(tái)聊天實(shí)例。項(xiàng)目整體界面仿制微信聊天app,實(shí)現(xiàn)了消息/表情發(fā)送、圖片預(yù)覽、Popwin長(zhǎng)按彈窗、視頻/紅包/朋友圈功能。

技術(shù)棧
使用技術(shù):Flutter 1.12.13/Dart 2.7.0
視頻組件:chewie: ^0.9.7
圖片/拍照:image_picker: ^0.6.6+1
圖片預(yù)覽組件:photo_view: ^0.9.2
彈窗組件:showModalBottomSheet/AlertDialog/SnackBar
本地存儲(chǔ):shared_preferences: ^0.5.7+1
字體圖標(biāo):阿里iconfont字體圖標(biāo)庫(kù)



flutter登錄|注冊(cè)表單驗(yàn)證
flutter提供了兩個(gè)文本框組件:TextField
?和?TextFormField
本文是使用TextField
實(shí)現(xiàn),并在文本框后添加清空文本框/密碼查看圖標(biāo)
TextField(
? keyboardType: TextInputType.phone,
? controller: TextEditingController.fromValue(TextEditingValue(
? ? text: formObj['tel'],
? ? selection: new TextSelection.fromPosition(TextPosition(affinity: TextAffinity.downstream, offset: formObj['tel'].length))
? )),
? decoration: InputDecoration(
? ? hintText: "請(qǐng)輸入手機(jī)號(hào)",
? ? isDense: true,
? ? hintStyle: TextStyle(fontSize: 14.0),
? ? suffixIcon: Visibility(
? ? ? visible: formObj['tel'].isNotEmpty,
? ? ? child: InkWell(
? ? ? ? child: GStyle.iconfont(0xe69f, color: Colors.grey, size: 14.0), onTap: () {
? ? ? ? ? setState(() { formObj['tel'] = ''; });
? ? ? ? }
? ? ? ),
? ? ),
? ? border: OutlineInputBorder(borderSide: BorderSide.none)
? ),
? onChanged: (val) {
? ? setState(() { formObj['tel'] = val; });
? },
)
TextField(
? decoration: InputDecoration(
? ? hintText: "請(qǐng)輸入密碼",
? ? isDense: true,
? ? hintStyle: TextStyle(fontSize: 14.0),
? ? suffixIcon: InkWell(
? ? ? child: Icon(formObj['isObscureText'] ? Icons.visibility_off : Icons.visibility, color: Colors.grey, size: 14.0),
? ? ? onTap: () {
? ? ? ? setState(() {
? ? ? ? ? formObj['isObscureText'] = !formObj['isObscureText'];
? ? ? ? });
? ? ? },
? ? ),
? ? border: OutlineInputBorder(borderSide: BorderSide.none)
? ),
? obscureText: formObj['isObscureText'],
? onChanged: (val) {
? ? setState(() { formObj['pwd'] = val; });
? },
)
通過(guò)flutter提供的SnackBar來(lái)提示消息
final _scaffoldkey = new GlobalKey<ScaffoldState>();
void _snackbar(String title, {Color color}) {
? ? _scaffoldkey.currentState.showSnackBar(SnackBar(
? ? ? backgroundColor: color ?? Colors.redAccent,
? ? ? content: Text(title),
? ? ? duration: Duration(seconds: 1),
? ? ));
}









flutter桌面app啟動(dòng)圖標(biāo)右上角圓點(diǎn)|未讀消息小紅點(diǎn)

如上圖:在flutter中沒(méi)有圓點(diǎn)提示組件,需要自己封裝實(shí)現(xiàn);
class GStyle {
? ? // 消息紅點(diǎn)
? ? static badge(int count, {Color color = Colors.red, bool isdot = false, double height = 18.0, double width = 18.0}) {
? ? ? ? final _num = count > 99 ? '···' : count;
? ? ? ? return Container(
? ? ? ? ? ? alignment: Alignment.center, height: !isdot ? height : height/2, width: !isdot ? width : width/2,
? ? ? ? ? ? decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(100.0)),
? ? ? ? ? ? child: !isdot ? Text('$_num', style: TextStyle(color: Colors.white, fontSize: 12.0)) : null
? ? ? ? );
? ? }
}
flutter聊天頁(yè)面模塊功能
flutter中TextField文本框提供的maxLines屬性可實(shí)現(xiàn)多行/換行文本,不過(guò)默認(rèn)會(huì)有個(gè)高度,可在外層加個(gè)容器限制最小高度,然后設(shè)置 maxLines: null、?keyboardType: TextInputType.multiline

Container(
? ? margin: GStyle.margin(10.0),
? ? decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(3.0)),
? ? constraints: BoxConstraints(minHeight: 30.0, maxHeight: 150.0),
? ? child: TextField(
? ? ? ? maxLines: null,
? ? ? ? keyboardType: TextInputType.multiline,
? ? ? ? decoration: InputDecoration(
? ? ? ? ? hintStyle: TextStyle(fontSize: 14.0),
? ? ? ? ? isDense: true,
? ? ? ? ? contentPadding: EdgeInsets.all(5.0),
? ? ? ? ? border: OutlineInputBorder(borderSide: BorderSide.none)
? ? ? ? ),
? ? ? ? controller: _textEditingController,
? ? ? ? focusNode: _focusNode,
? ? ? ? onChanged: (val) {
? ? ? ? ? setState(() {
? ? ? ? ? ? editorLastCursor = _textEditingController.selection.baseOffset;
? ? ? ? ? });
? ? ? ? },
? ? ? ? onTap: () {handleEditorTaped();},
? ? ),
),



通過(guò)ListView里controller屬性提供的jumpTo
方法及_msgController.position.maxScrollExtent
ScrollController _msgController = new ScrollController();
ListView(
? ? controller: _msgController,
? ? padding: EdgeInsets.all(10.0),
? ? children: renderMsgTpl(),
)
// 滾動(dòng)消息至聊天底部
void scrollMsgBottom() {
? ? timer = Timer(Duration(milliseconds: 100), () => _msgController.jumpTo(_msgController.position.maxScrollExtent));
}





okey,基于flutter+dart開(kāi)發(fā)聊天實(shí)例就介紹到這里,后續(xù)會(huì)分享更多實(shí)戰(zhàn)案例!!????
作者:xiaoyan2019
https://www.bilibili.com/read/cv5983396
出處: bilibili