1、项目介绍
Flutter
是目前比较流行的跨平台开发技术,凭借其出色的性能获得很多前端技术爱好者的关注,比如 阿里闲鱼
, 美团
, 腾讯
等大公司都有投入相关案例生产使用。
flutter_chatroom项目 是基于 Flutter+Dart+chewie+photo_view+image_picker
等技术开发的跨平台仿微信app聊天界面应用,实现了消息/表情发送、图片预览、长按菜单、红包/小视频/朋友圈等功能。
2、技术框架
- 使用技术:Flutter 1.12.13/Dart 2.7.0
- 视频组件:chewie: ^0.9.7
- 图片/拍照:image_picker: ^0.6.6+1
- 图片预览组件:photo_view: ^0.9.2
- 弹窗组件:showModalBottomSheet/AlertDialog/SnackBar
- 本地存储:shared_preferences: ^0.5.7+1
- 字体图标:阿里iconfont字体图标库
鉴于flutter基于dart语言,需要安装 Dart Sdk / Flutter Sdk
,至于如何搭建开发环境,可以去官网查阅文档资料
使用vscode编辑器,可先安装 Dart
、 Flutter
、 Flutter widget snippets
等扩展插件
3、flutter沉浸式状态栏/底部tabbar
flutter中如何实现顶部全背景沉浸式透明状态栏(去掉状态栏黑色半透明背景),去掉右上角banner,可以去看这篇文章
https://segmentfault.com/a/11...4、flutter图标组件/IconData自定义封装组件
Icon(Icons.search) Icon(IconData(0xe60e, fontFamily:'iconfont'), size:24.0)
使用第二种方式需要先下载阿里图标库字体文件,然后在pubspec.yaml中引入字体
class GStyle { // __ 自定义图标 static iconfont(int codePoint, {double size = 16.0, Color color}) { return Icon( IconData(codePoint, fontFamily: 'iconfont', matchTextDirection: true), size: size, color: color, ); } }
调用非常简单,可自定义颜色、字体大小;
GStyle.iconfont(0xe635, color: Colors.orange, size: 17.0)
5、flutter实现badge红点/圆点提示
如上图:在flutter中没有圆点提示组件,需要自己封装实现;
class GStyle { // 消息红点 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 ); } }
支持自定义红点大小、颜色,默认数字超过99就...显示;
GStyle.badge(0, isdot:true)
GStyle.badge(13)
GStyle.badge(29, color: Colors.orange, height: 15.0, width: 15.0)
6、flutter长按自定义弹窗
- 在flutter中如何实现长按,并在长按位置弹出菜单,类似微信消息长按弹窗效果;
通过 InkWell
组件提供的 onTapDown
事件获取坐标点实现
InkWell( splashColor: Colors.grey[200], child: Container(...), onTapDown: (TapDownDetails details) { _globalPositionX = details.globalPosition.dx; _globalPositionY = details.globalPosition.dy; }, onLongPress: () { _showPopupMenu(context); }, ),
// 长按弹窗 double _globalPositionX = 0.0; //长按位置的横坐标 double _globalPositionY = 0.0; //长按位置的纵坐标 void _showPopupMenu(BuildContext context) { // 确定点击位置在左侧还是右侧 bool isLeft = _globalPositionX > MediaQuery.of(context).size.width/2 ? false : true; // 确定点击位置在上半屏幕还是下半屏幕 bool isTop = _globalPositionY > MediaQuery.of(context).size.height/2 ? false : true; showDialog( context: context, builder: (context) { return Stack( children: <Widget>[ Positioned( top: isTop ? _globalPositionY : _globalPositionY - 200.0, left: isLeft ? _globalPositionX : _globalPositionX - 120.0, width: 120.0, child: Material( ... ), ) ], ); } ); }
- flutter如何实现去掉AlertDialog弹窗大小限制?
可通过 SizedBox
和无限制容器 UnconstrainedBox
组件实现
void _showCardPopup(BuildContext context) { showDialog( context: context, builder: (context) { return UnconstrainedBox( constrainedAxis: Axis.vertical, child: SizedBox( width: 260, child: AlertDialog( content: Container( ... ), elevation: 0, contentPadding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0), ), ), ); } ); }
7、flutter登录/注册表单|本地存储
flutter提供了两个文本框组件: TextField
和 TextFormField
本文是使用 TextField
实现,并在文本框后添加清空文本框/密码查看图标
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: "请输入手机号", 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: "请输入密码", 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; }); }, )
验证消息提示则是使用flutter提供的SnackBar实现
// SnackBar提示 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), )); }
另外本地存储使用的是 shared\_preferences
,至于如何使用可参看
void handleSubmit() async { if(formObj['tel'] == '') { _snackbar('手机号不能为空'); }else if(!Util.checkTel(formObj['tel'])) { _snackbar('手机号格式有误'); }else if(formObj['pwd'] == '') { _snackbar('密码不能为空'); }else { // ...接口数据 // 设置存储信息 final prefs = await SharedPreferences.getInstance(); prefs.setBool('hasLogin', true); prefs.setInt('user', int.parse(formObj['tel'])); prefs.setString('token', Util.setToken()); _snackbar('恭喜你,登录成功', color: Colors.greenAccent[400]); Timer(Duration(seconds: 2), (){ Navigator.pushNamedAndRemoveUntil(context, '/tabbarpage', (route) => route == null); }); } }
8、flutter聊天页面功能
- 在flutter中如何实现类似上图编辑器功能?通过TextField提供的多行文本框属性
maxLines
就可实现。
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();}, ), ),
- flutter实现滚动聊天信息到最底部
通过ListView里controller属性提供的 jumpTo
方法及 _msgController.position.maxScrollExtent
ScrollController _msgController = new ScrollController(); ... ListView( controller: _msgController, padding: EdgeInsets.all(10.0), children: renderMsgTpl(), ) // 滚动消息至聊天底部 void scrollMsgBottom() { timer = Timer(Duration(milliseconds: 100), () => _msgController.jumpTo(_msgController.position.maxScrollExtent)); }
行了,基于flutter/dart开发聊天室实例就介绍到这里,希望能喜欢~~:muscle::muscle:
最后附上electron桌面端应用实例
electron聊天室|vue+electron-vue仿微信客户端|electron桌面聊天以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- SWOOLE开发实时聊天系统(十)用户断开聊天
- 聊天私服 Akaxin 0.5.4 发布,优化聊天、注册逻辑
- Netty网络聊天(一) 聊天室的实战(最易懂)
- h5聊天室模板|仿微信聊天室html5
- 创建聊天机器人,第 3 部分: 使用认知(或人工智能)服务增强聊天机器人
- Vue2 全家桶仿 微信App 项目,支持多人在线聊天和机器人聊天
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Introduction to Linear Optimization
Dimitris Bertsimas、John N. Tsitsiklis / Athena Scientific / 1997-02-01 / USD 89.00
"The true merit of this book, however, lies in its pedagogical qualities which are so impressive..." "Throughout the book, the authors make serious efforts to give geometric and intuitive explanations......一起来看看 《Introduction to Linear Optimization》 这本书的介绍吧!