天天看點

美團flutter_flutter+dart仿微信App界面聊天執行個體

Flutter 是 谷歌 開源的 UI 架構,旨在幫助開發者通過一套代碼庫高效建構多平台精美應用,支援移動、Web、桌面和嵌入式平台。相比較目前的混合開發方案,Flutter 提供了大量的文檔,能非常快速且友好的讓你加入到這個大家庭,針對移動端,Flutter 提供了符合 Android 風格的 Material 和符合 iOS 風格的 Cupertino,同時對不同平台也做了不同的相容。比如 閑魚,美團,騰訊 等大廠都有相關案例使用。感興趣的同學可以關注:

https://github.com/flutter/flutter

https://flutter.cn/

https://flutterchina.club/

https://pub.flutter-io.cn/

https://www.dartcn.com/

美團flutter_flutter+dart仿微信App界面聊天執行個體

項目介紹

基于flutter+dart等技術開發仿微信手機端App聊天執行個體,實作消息發送/編輯器光标處插入表情,圖檔縮放預覽,長按PopupWin菜單,視訊/紅包/朋友圈等功能。

美團flutter_flutter+dart仿微信App界面聊天執行個體

架構技術

  • 編碼/技術:VS + Flutter 1.12.13/Dart 2.7.0
  • 圖檔/拍照:image_picker: ^0.6.6+1
  • 圖檔預覽元件:photo_view: ^0.9.2
  • 視訊元件:chewie: ^0.9.7
  • 存儲元件:shared_preferences: ^0.5.7+1
  • 字型圖示:阿裡iconfont字型圖示庫
美團flutter_flutter+dart仿微信App界面聊天執行個體

flutter項目結構/主入口main.dart配置

/** * @tpl Flutter入口頁面配置 */import 'package:flutter/material.dart';// 引入公共樣式import 'styles/common.dart';// 引入底部Tabbar頁面導航import 'components/tabbar.dart';// 引入位址路由import 'router/routes.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter App',      debugShowCheckedModeBanner: false,      theme: ThemeData(        primaryColor: GStyle.appbarColor,      ),      home: TabBarPage(),      onGenerateRoute: onGenerateRoute,    );  }}
           
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
  • 會話、通訊錄、我三大子產品,通過flutter導航切換BottomNavigationBar元件封裝到tabbar頁面
  • 底部tab是放在 Scaffold 的 bottomNavigationBar 中,頂部tab是放在 AppBar 的 bottom 中,也就是标題欄之下
美團flutter_flutter+dart仿微信App界面聊天執行個體
美團flutter_flutter+dart仿微信App界面聊天執行個體
bottomNavigationBar: BottomNavigationBar(  backgroundColor: GStyle.tabbarColor,  fixedColor: GStyle.primaryColor,  type: BottomNavigationBarType.fixed,  elevation: 1.0,  unselectedFontSize: 12.0,  selectedFontSize: 12.0,  currentIndex: _currentTabIndex,  items: [    BottomNavigationBarItem(      icon: Stack(        alignment: Alignment(6,-4),        children: [          GStyle.iconfont(0xe62a, size: 21.0), GStyle.badge(13),        ],      ),       title: Text('會話')    ),    BottomNavigationBarItem(      icon: GStyle.iconfont(0xe600, size: 21.0),      title: Text('通訊錄')    ),    BottomNavigationBarItem(      icon: Stack(        alignment: Alignment(1.5, -1.5),        children: [          GStyle.iconfont(0xe6b4, size: 21.0), GStyle.badge(0, isdot: true),        ],      ),      title: Text('我')    ),  ],  onTap: (int index) {    setState(() {      _currentTabIndex = index;    });  },)
           
appBar: new AppBar(  ...  ///tabBar控件  bottom: new TabBar(    ///頂部時,tabBar為可以滑動的模式    isScrollable: true,    ///必須有的控制器,與pageView的控制器同步    controller: _tabController,    ///每一個tab item,是一個List    tabs: _tabItems,    ///tab底部選中條顔色    indicatorColor: _indicatorColor,  ),  ...)
           

flutter中使用阿裡iconfont字型圖示

由于flutter自帶圖示不能滿足項目需求,是以項目中使用的圖示是阿裡iconfont字型圖示庫

在pubspec.yaml裡添加字型配置

美團flutter_flutter+dart仿微信App界面聊天執行個體
Icon(IconData(0xe60e, fontFamily:'iconfont'), size:24.0)
           

IconData第一個參數是字型code,到這一步自定義字型圖示就好了,每次都這樣調用顯得不優雅,隻能作如下抽離封裝。

class GStyle {      // __ 自定義圖示      static iconfont(int codePoint, {double size = 16.0, Color color}) {          return Icon(              IconData(codePoint, fontFamily: 'iconfont', matchTextDirection: true),              size: size,              color: color,          );      }  }
           

這樣調用的時候隻需傳入字型code就行,支援自定義圖示大小、顔色

GStyle.iconfont(0xe60e)GStyle.iconfont(0xe60e, color: Colors.orange, size: 21.0)
           

flutter未讀資訊圓形數字提示|紅點提醒

如下圖:類似這種未讀消息提醒,在app中很常見,給人很直覺的消息提示。在flutter中并沒有提供這個元件,隻能自行封裝。

美團flutter_flutter+dart仿微信App界面聊天執行個體
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        );    }}
           

預設背景色是紅色、大小為18,數字超過99會以...顯示。

//紅點GStyle.badge(0, isdot:true)//預設數字13圓形GStyle.badge(13)//預設數字68, 橘色 大小15GStyle.badge(68, color: Colors.orange, height: 15.0, width: 15.0)
           

flutter自定義修改彈窗

flutter中提供了多種豐富的彈窗元件:對話框AlertDialog、底部彈出框showModalBottomSheet、底部弱提示框SnackBar

  • flutter實作類似微信在長按位置彈出菜單
美團flutter_flutter+dart仿微信App界面聊天執行個體

可通過flutter中InkWell元件提供的onTapDown擷取長按坐标點,onLongPress長按事件彈出菜單

/** * @tpl 首頁模闆 */import 'package:flutter/material.dart';import '../../styles/common.dart';import '../../components/headerbar.dart';class IndexPage extends StatefulWidget {  @override  _IndexPageState createState() => _IndexPageState();}class _IndexPageState extends State {  double _globalPositionX = 0.0; //點選位置的橫坐标  double _globalPositionY = 0.0; //點選位置的縱坐标  @override  Widget build(BuildContext context) {    return Scaffold(      backgroundColor: GStyle.backgroundColor,      appBar: HeaderBar('Flutter聊天室'),      body: Container(        child: ListView(          children: [            InkWell(              splashColor: Colors.grey[200],              child: Container(                ...              ),              onTap: () {...},              //擷取長按坐标點              onTapDown: (TapDownDetails details) {                _globalPositionX = details.globalPosition.dx;                _globalPositionY = details.globalPosition.dy;              },              onLongPress: () {                _showPopupMenu(context);              },            ),          ],        ),      ),    );  }  // 彈出長按菜單  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: [            Positioned(              top: isTop ? _globalPositionY : _globalPositionY - 200,              left: isLeft ? _globalPositionX : _globalPositionX - 120,              width: 120,              child: Material(                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)), //圓角                child: Column(                  children: [                    ...元件内容                  ],                ),              ),            )          ],        );      }    );  }}
           
  • flutter對話框SimpleDialog,可以顯示附加的提示和操作,通常配合SimpleDialogOption一起使用
美團flutter_flutter+dart仿微信App界面聊天執行個體
/** * @tpl 通訊錄頁面 */import 'package:flutter/material.dart';import '../../styles/common.dart';import '../../components/headerbar.dart';class ContactPage extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      backgroundColor: GStyle.backgroundColor,      appBar: HeaderBar('通訊錄'),      body: DefaultTabController(        length: 2,        child: Scaffold(          appBar: TabBar(            tabs: [              Tab(text: '好友清單'),Tab(text: '推薦好友'),            ],            unselectedLabelColor: Colors.black54,            labelColor: GStyle.c_0091ea,            indicatorColor: GStyle.c_0091ea,            indicatorSize: TabBarIndicatorSize.label,          ),          body: TabBarView(            children: [              //tab1頁面              Container(                child: ListView(                  children: [                    InkWell(                      splashColor: Colors.grey[200],                      child: Container(                        ...                      ),                      onTap: () {                        Navigator.pushNamed(context, '/uinfo');                      },                      onLongPress: () {                        _showSimplePopMenu(context);                      },                    ),                  ],                ),              ),              //tab2頁面              Container(                ...              ),            ],          )        )      ),    );  }  void _showSimplePopMenu(BuildContext context) {    showDialog(      context: context,      builder: (context) {        return SimpleDialog(          // title: Text('标題'),          contentPadding: EdgeInsets.symmetric(vertical: 5.0),          elevation: 0,          children: [            SimpleDialogOption(              child: Padding(padding: EdgeInsets.symmetric(vertical: 5.0), child: Text('添加備注')),              onPressed: () {},            ),            ...          ],        );      }    );  }}
           
  • flutter底部面闆showModalBottomSheet對話框,相當于彈出了一個新頁面
美團flutter_flutter+dart仿微信App界面聊天執行個體
/** * @tpl 好友資訊頁面 */import 'package:flutter/material.dart';import '../../styles/common.dart';import '../../components/headerbarNav.dart';class UinfoPage extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      backgroundColor: GStyle.backgroundColor,      appBar: HeaderBarNav('',        leading: IconButton(icon: GStyle.iconfont(0xe65c, size: 17.0), onPressed: () {Navigator.pop(context);}),        actions: [          IconButton(icon: GStyle.iconfont(0xe93e, size: 17.0), onPressed: () {_showBottomSheet(context);}),        ]      ),      body: Container(        ...      ),    );  }  // 底部彈窗  void _showBottomSheet(BuildContext context) {    showModalBottomSheet(      context: context,      builder: (context) {        return Column(          mainAxisSize: MainAxisSize.min, //主軸方向占有空間的值,預設是max          children: [            ListTile(              title: Row(                mainAxisAlignment: MainAxisAlignment.center,                 children: [Text('推薦給朋友', style: TextStyle(fontSize: 14))]              ),              onTap: () {},            ),            ...          ],        );      },      // 圓角      shape: RoundedRectangleBorder(          borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0))      )    );  }}
           
  • flutter中AlertDialog對話框

在flutter中AlertDialog彈窗預設大小是固定的,如何去掉寬高限制?

通過SizedBox和無限制容器UnconstrainedBox元件配合實作,如下圖寬度設定為260,高度是自适應

美團flutter_flutter+dart仿微信App界面聊天執行個體
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),          ),        ),      );    }    );}
           

行,到這裡基于flutter/dart開發聊天執行個體就介紹完了,希望這些分享能有些許幫助!!

最後附上兩個最近執行個體項目

electron-vue仿微信用戶端|electron聊天執行個體

uniapp+nvue仿抖音效果|小視訊直播室