Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于flutter3.x+material-design3仿微信App应用实战

基于flutter3.x+material-design3仿微信App应用实战

原创
作者头像
andy2018
发布于 2024-02-07 01:45:44
发布于 2024-02-07 01:45:44
1.2K0
举报
文章被收录于专栏:h5h5

flutter3-wchat一款基于flutter3+dart3+material-ui技术构建的跨多端仿微信聊天项目。

flutter3已经支持全终端项目开发,可编译到android/ios/windows/macos/linux/web等多个平台。

使用技术

  • 开发工具:vscode
  • 框架技术:flutter3.16.5+dart3.2.3
  • UI组件库:material-design3
  • 弹窗组件:showDialog/SimpleDialog/showModalBottomSheet/AlertDialog
  • 图片预览:photo_view^0.14.0
  • 本地缓存:shared_preferences^2.2.2
  • 下拉刷新:easy_refresh^3.3.4
  • toast提示:toast^0.3.0
  • 网址预览组件:url_launcher^6.2.4

项目结构

使用flutter create flutter_chat命令创建项目,生成的多端结构如下:

在开始开发之前,需要先配置好相应的开发环境。

https://flutter.dev/

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

https://www.dartcn.com/

入口配置main.dart

代码语言:typescript
AI代码解释
复制
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:toast/toast.dart';

// 引入公共样式
import 'styles/index.dart';

// 引入底部tabbar
import 'components/tabbar.dart';

// 引入路由管理
import 'router/index.dart';

// 错误模块
import '../views/error/index.dart';

void main() {
    runApp(const MyApp());
}

DateTime? lastPopTime;

class MyApp extends StatelessWidget {
    const MyApp({ super.key });

  // 退出app提示
  Future<bool> appOnPopInvoked(didPop) async {
    if(lastPopTime == null || DateTime.now().difference(lastPopTime!) > const Duration(seconds: 2)) {
      lastPopTime = DateTime.now();
      Toast.show('再按一次退出应用');
      return false;
    }
    SystemNavigator.pop();
    return true;
  }
  
    @override
    Widget build(BuildContext context){
    ToastContext().init(context);

        return MaterialApp(
            title: 'Flutter Chat',
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
                primaryColor: FStyle.primaryColor,
                useMaterial3: true,
        // windows桌面端字体粗细不一样
        fontFamily: Platform.isWindows ? 'Microsoft YaHei' : null,
            ),
            // home: const FTabBar(),
      home: PopScope(
        // canPop: false,
        onPopInvoked: appOnPopInvoked,
        child: const FTabBar(),
      ),
      // 初始路由
      // initialRoute: '/',
      // 自定义路由
            onGenerateRoute: onGenerateRoute,
      // 错误路由
      onUnknownRoute: (settings) {
        return MaterialPageRoute(builder: (context) => const Error());
      },
        );
    }
}

Flutter3表单验证

代码语言:typescript
AI代码解释
复制
Timer? timer;
String vcodeText = '获取验证码';
bool disabled = false;
int time = 60;

// 60s倒计时
void handleVcode() {
  if(authObj['tel'] == '') {
    snackbar('手机号不能为空');
  }else if(!Utils.checkTel(authObj['tel'])) {
    snackbar('手机号格式不正确');
  }else {
    setState(() {
      disabled = true;
    });
    startTimer();
  }
}
startTimer() {
  timer = Timer.periodic(const Duration(seconds: 1), (timer) {
    setState(() {
      if(time > 0) {
        vcodeText = '获取验证码(${time--})';
      }else {
        vcodeText = '获取验证码';
        time = 60;
        disabled = false;
        timer.cancel();
      }
    });
  });
  snackbar('短信验证码已发送,请注意查收', color: Colors.green);
}
  • 文本框/按钮圆角渐变色

代码语言:typescript
AI代码解释
复制
Container(
  height: 40.0,
  margin: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 30.0),
  decoration: BoxDecoration(
    color: Colors.white,
    border: Border.all(color: const Color(0xffdddddd)),
    borderRadius: BorderRadius.circular(15.0),
  ),
  child: Row(
    children: [
      Expanded(
        child: TextField(
          keyboardType: TextInputType.phone,
          controller: fieldController,
          decoration: InputDecoration(
            hintText: '输入手机号',
            suffixIcon: Visibility(
              visible: authObj['tel'].isNotEmpty,
              child: InkWell(
                hoverColor: Colors.transparent,
                highlightColor: Colors.transparent,
                splashColor: Colors.transparent,
                onTap: handleClear,
                child: const Icon(Icons.clear, size: 16.0,),
              )
            ),
            contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 12.0),
            border: const OutlineInputBorder(borderSide: BorderSide.none),
          ),
          onChanged: (value) {
            setState(() {
              authObj['tel'] = value;
            });
          },
        ),
      )
    ],
  ),
),

渐变色是通过Container组件gradient实现。

代码语言:typescript
AI代码解释
复制
Container(
  margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 30.0),
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(15.0),
    // 自定义按钮渐变色
    gradient: const LinearGradient(
      begin: Alignment.topLeft,
      end: Alignment.bottomRight,
      colors: [
        Color(0xFF0091EA), Color(0xFF07C160)
      ],
    )
  ),
  child: SizedBox(
    width: double.infinity,
    height: 45.0,
    child: FilledButton(
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(Colors.transparent),
        shadowColor: MaterialStateProperty.all(Colors.transparent),
        shape: MaterialStatePropertyAll(
          RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0))
        )
      ),
      onPressed: handleSubmit,
      child: const Text('登录', style: TextStyle(fontSize: 18.0),),
    ),
  )
),

Flutter3渐变色导航条

flutter中Appbar组件background属性只能单纯设置颜色,不能设置渐变背景。可通过FlexibleSpace属性设置背景渐变色/渐变背景图。

代码语言:typescript
AI代码解释
复制
AppBar(
  title: Text('Flutter3-Chat'),
  flexibleSpace: Container(
    decoration: const BoxDecoration(
      gradient: LinearGradient(
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
        colors: [
          Color(0xFF0091EA), Color(0xFF07C160)
        ],
      )
    ),
  )
),

flutter3实现各种弹窗效果。

代码语言:typescript
AI代码解释
复制
// 关于弹窗
void aboutAlertDialog(BuildContext context) {
  showDialog(
    context: context,
    builder: (context) {
      return UnconstrainedBox(
        constrainedAxis: Axis.vertical,
        child: SizedBox(
          width: 320.0,
          child: AlertDialog(
            contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
            backgroundColor: Colors.white,
            surfaceTintColor: Colors.white,
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
            content: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Image.asset('assets/images/logo.png', width: 90.0, height: 90.0, fit: BoxFit.cover,),
                  const SizedBox(height: 10.0),
                  const Text('Flutter3-WChat', style: TextStyle(color: Color(0xFF0091EA), fontSize: 22.0),),
                  const SizedBox(height: 5.0),
                  const Text('基于flutter3+dart3开发跨平台仿微信App聊天实例。', style: TextStyle(color: Colors.black45),),
                  const SizedBox(height: 20.0),
                  Text('©2024/01 Andy   Q: 282310962', style: TextStyle(color: Colors.grey[400], fontSize: 12.0),),
                ],
              ),
            ),
          ),
        ),
      );
    }
  );
}

// 二维码名片弹窗
void qrcodeAlertDialog(BuildContext context) {
  showDialog(
    context: context,
    builder: (context) {
      return UnconstrainedBox(
        constrainedAxis: Axis.vertical,
        child: SizedBox(
          width: 320.0,
          child: AlertDialog(
            contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
            backgroundColor: const Color(0xFF07C160),
            surfaceTintColor: const Color(0xFF07C160),
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3.0)),
            content: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Image.asset('assets/images/qrcode.png', width: 250.0, fit: BoxFit.cover,),
                  const SizedBox(height: 15.0),
                  const Text('扫一扫,加我公众号', style: TextStyle(color: Colors.white60, fontSize: 14.0,),),
                ],
              ),
            ),
          ),
        ),
      );
    }
  );
}

// 退出登录弹窗
void logoutAlertDialog(BuildContext context) {
  showDialog(
    context: context,
    builder: (context) {
      return AlertDialog(
        content: const Text('确定要退出登录吗?', style: TextStyle(fontSize: 16.0),),
        backgroundColor: Colors.white,
        surfaceTintColor: Colors.white,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
        elevation: 2.0,
        actionsPadding: const EdgeInsets.all(15.0),
        actions: [
          TextButton(
            onPressed: () {Navigator.of(context).pop();},
            child: const Text('取消', style: TextStyle(color: Colors.black54),)
          ),
          TextButton(
            onPressed: handleLogout,
            child: const Text('退出登录', style: TextStyle(color: Colors.red),)
          ),
        ],
      );
    }
  );
}

flutter微信朋友圈九宫格

代码语言:typescript
AI代码解释
复制
GroupZone(images: item['images']),

GroupZone(
  images: uploadList,
  album: true,
  onChoose: () async {
    Toast.show('选择手机相册图片', duration: 2, gravity: 1);
  },
),
代码语言:typescript
AI代码解释
复制
// 创建可点击预览图片
createImage(BuildContext context, String img, int key) {
  return GestureDetector(
    child: Hero(
      tag: img, // 放大缩小动画效果标识
      child: img == '+' ? 
      Container(color: Colors.transparent, child: const Icon(Icons.add, size: 30.0, color: Colors.black45),)
      :
      Image.asset(
        img,
        width: width,
        fit: BoxFit.contain,
      ),
    ),
    onTap: () {
      // 选择图片
      if(img == '+') {
        onChoose!();
      }else {
        Navigator.of(context).push(FadeRoute(route: ImageViewer(
          images: album ? imgList!.sublist(0, imgList!.length - 1) : imgList,
          index: key,
        )));
      }
    },
  );
}

Flutter3微信聊天语音模块

代码语言:typescript
AI代码解释
复制
// 语音
Offstage(
  offstage: !voiceBtnEnable,
  child: GestureDetector(
    child: Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(5),
      ),
      alignment: Alignment.center,
      height: 40.0,
      width: double.infinity,
      child: Text(voiceTypeMap[voiceType], style: const TextStyle(fontSize: 15.0),),
    ),
    onPanStart: (details) {
      setState(() {
        voiceType = 1;
        voicePanelEnable = true;
      });
    },
    onPanUpdate: (details) {
      Offset pos = details.globalPosition;
      double swipeY = MediaQuery.of(context).size.height - 120;
      double swipeX = MediaQuery.of(context).size.width / 2 + 50;
      setState(() {
        if(pos.dy >= swipeY) {
          voiceType = 1; // 松开发送
        }else if (pos.dy < swipeY && pos.dx < swipeX) {
          voiceType = 2; // 左滑松开取消
        }else if (pos.dy < swipeY && pos.dx >= swipeX) {
          voiceType = 3; // 右滑语音转文字
        }
      });
    },
    onPanEnd: (details) {
      // print('停止录音');
      setState(() {
        switch(voiceType) {
          case 1:
            Toast.show('发送录音文件', duration: 1, gravity: 1);
            voicePanelEnable = false;
            break;
          case 2:
            Toast.show('取消发送', duration: 1, gravity: 1);
            voicePanelEnable = false;
            break;
          case 3:
            Toast.show('语音转文字', duration: 1, gravity: 1);
            voicePanelEnable = true;
            voiceToTransfer = true;
            break;
        }
        voiceType = 0;
      });
    },
  ),
),

按住说话/左滑取消/右滑转语音功能。

代码语言:typescript
AI代码解释
复制
// 录音主体(按住说话/松开取消/语音转文本)
Visibility(
  visible: voicePanelEnable,
  child: Material(
    color: const Color(0xDD1B1B1B),
    child: Stack(
      children: [
        // 取消发送+语音转文字
        Positioned(
          bottom: 120,
          left: 30,
          right: 30,
          child: Visibility(
            visible: !voiceToTransfer,
            child: Column(
              children: [
                // 语音动画层
                Stack(
                  children: [
                    Container(
                      height: 70.0,
                      margin: const EdgeInsets.symmetric(horizontal: 50.0),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(15.0),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Image.asset('assets/images/voice_record.gif', height: 30.0,)
                        ],
                      ),
                    ),
                    Positioned(
                      right: (MediaQuery.of(context).size.width - 60) / 2,
                      bottom: 1,
                      child: RotatedBox(
                        quarterTurns: 0,
                        child: CustomPaint(painter: ArrowShape(arrowColor: Colors.white, arrowSize: 10.0)),
                      )
                    ),
                  ],
                ),
                const SizedBox(height: 50.0,),
                // 操作项
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    // 取消发送
                    Container(
                      height: 60.0,
                      width: 60.0,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(50.0),
                        color: voiceType == 2 ? Colors.red : Colors.black38,
                      ),
                      child: const Icon(Icons.close, color: Colors.white54,),
                    ),
                    // 语音转文字
                    Container(
                      height: 60.0,
                      width: 60.0,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(50.0),
                        color: voiceType == 3 ? Colors.green : Colors.black38,
                      ),
                      child: const Icon(Icons.translate, color: Colors.white54,),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
        // 语音转文字(识别结果状态)
        Positioned(
          bottom: 120,
          left: 30,
          right: 30,
          child: Visibility(
            visible: voiceToTransfer,
            child: Column(
              children: [
                // 提示结果
                Stack(
                  children: [
                    Container(
                      height: 100.0,
                      decoration: BoxDecoration(
                        color: Colors.red,
                        borderRadius: BorderRadius.circular(15.0),
                      ),
                      child: const Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(Icons.info, color: Colors.white,),
                          Text('未识别到文字。', style: TextStyle(color: Colors.white),),
                        ],
                      ),
                    ),
                    Positioned(
                      right: 35.0,
                      bottom: 1,
                      child: RotatedBox(
                        quarterTurns: 0,
                        child: CustomPaint(painter: ArrowShape(arrowColor: Colors.red, arrowSize: 10.0)),
                      )
                    ),
                  ],
                ),
                const SizedBox(height: 50.0,),
                // 操作项
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    GestureDetector(
                      child: Container(
                        height: 60.0,
                        width: 60.0,
                        decoration: const BoxDecoration(
                          color: Colors.transparent,
                        ),
                        child: const Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Icon(Icons.undo, color: Colors.white54,),
                            Text('取消', style: TextStyle(color: Colors.white70),)
                          ],
                        ),
                      ),
                      onTap: () {
                        setState(() {
                          voicePanelEnable = false;
                          voiceToTransfer = false;
                        });
                      },
                    ),
                    GestureDetector(
                      child: Container(
                        height: 60.0,
                        width: 100.0,
                        decoration: const BoxDecoration(
                          color: Colors.transparent,
                        ),
                        child: const Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Icon(Icons.graphic_eq_rounded, color: Colors.white54,),
                            Text('发送原语音', style: TextStyle(color: Colors.white70),)
                          ],
                        ),
                      ),
                      onTap: () {},
                    ),
                    GestureDetector(
                      child: Container(
                        height: 60.0,
                        width: 60.0,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(50.0),
                          color: Colors.white12,
                        ),
                        child: const Icon(Icons.check, color: Colors.white12,),
                      ),
                      onTap: () {},
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
        // 提示文字(操作状态)
        Positioned(
          bottom: 120,
          left: 0,
          width: MediaQuery.of(context).size.width,
          child: Visibility(
            visible: !voiceToTransfer,
            child: Align(
              child: Text(voiceTypeMap[voiceType], style: const TextStyle(color: Colors.white70),),
            ),
          ),
        ),
        // 背景
        Align(
          alignment: Alignment.bottomCenter,
          child: Visibility(
            visible: !voiceToTransfer,
            child: Image.asset('assets/images/voice_record_bg.webp', width: double.infinity, height: 100.0, fit: BoxFit.fill),
          ),
        ),
        // 背景图标
        Positioned(
          bottom: 25,
          left: 0,
          width: MediaQuery.of(context).size.width,
          child: Visibility(
            visible: !voiceToTransfer,
            child: const Align(
              child: Icon(Icons.graphic_eq_rounded, color: Colors.black54,),
            ),
          ),
        ),
      ],
    ),
  ),
)

Okay,以上就是Flutter3/Dart3仿微信App聊天的一些知识分享。后续还会分享一些其它flutter实例项目。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
Flutter 创建一个很酷的 Booking App UI
这是一个非常酷的项目,您将在其中学习如何实现标签栏、具有水平滚动的列表视图以及如何创建底部Flutter 中的导航栏,所以不用多说,让我们开始吧。
徐建国
2021/08/02
6050
【10】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时
【10】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍
卓伊凡
2025/02/05
2390
Flutter 实现登录 UI
本文,我将解析怎么前构建一个用户交互的登录页面。这里,我使用 TextField 挂件,这方便用户输入用户名和密码。还使用 FlatButton 挂件,来处理一些动作。当然,我还使用了 Image 挂件来设定登录页面的 logo。
Jimmy_is_jimmy
2022/10/05
8520
Flutter 实现登录 UI
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍
卓伊凡
2025/02/07
780
2025实战-Flutter3.27仿携程app实例|flutter3.x酒店预订
2025開年原创新作Flutter3.27+Dart3.6跨平台仿携程/飞猪旅行酒店app预订系统。
andy2018
2025/02/22
1530
2025实战-Flutter3.27仿携程app实例|flutter3.x酒店预订
Flutter 黏贴卡动画效果
设计非常出色的动画会使UI感觉更直觉,应用程序具有光滑的外观和感觉,改善用户体验。Flutter的动画支持使实现各种动画类型变得容易。许多小部件,特别是“Material”小部件,都伴随着其设计规范中所描述的标准运动效果,但是与此同时,也可以自定义这些效果。
老孟Flutter
2021/04/22
2.3K0
Flutter 黏贴卡动画效果
flutter制作具有自定义导航栏的渐进式 Web 应用程序
我们将整个页面分成几个部分,以便于制定,我建议您这样做以获得更好的编程,让我们更详细地查看这些部分, NavigationBar()、 DashBoard()、 CalendarSpace(), 首先我们可以做导航栏部分
徐建国
2021/10/04
3.1K0
【Flutter 专题】117 图解 Dismissible 滑动清除 Widget
和尚在尝试在项目中实现类似于 iOS 邮箱邮件左右滑动删除对应邮件时,参考到 Flutter 提供的 Dismissible,虽与理想的有差别,但还是值得研究一下。
阿策小和尚
2021/03/16
1.3K0
flutter3_window_chat仿微信桌面端聊天实战
年前有给大家分享一款flutter3.x+dart3手机端聊天App实例。春节期间就又捣鼓了flutter3桌面端开发实践项目。
andy2018
2024/03/03
7910
自研flutter3.x实战仿抖音app短视频直播FlutterLive
flutter3.x_douyin基于flutter3+dart3+getx+meidaKit等技术开发抖音版app视频直播项目。
andy2018
2024/03/25
1.1K0
【Flutter】Flutter 布局组件 ( PhysicalModel 组件 )
代码示例 : PhysicalModel 组件裁剪 PageView 组件 , 将 PageView 组件裁剪成圆角矩形样式 ;
韩曙亮
2023/03/28
1.4K0
【Flutter】Flutter 布局组件 ( PhysicalModel 组件 )
本文主要介绍flutter聊天应用程序
在本教程中,我将向您展示如何使用 Flutter 构建一个完整的聊天应用程序。对于这一部分,我们将创建应用程序的 UI 原型,然后我将向您展示如何使用 firebase 创建后端服务并创建聊天系统。
徐建国
2021/07/31
7550
【Flutter 专题】124 日常问题小结 (三) 自定义 Dialog 二三事
针对日常不同的需求,我们时常需要自定义 Dialog,而和尚在尝试过程中遇到一些小问题,简单记录总结一下;
阿策小和尚
2021/06/08
1.2K0
【Flutter 专题】124 日常问题小结 (三) 自定义 Dialog 二三事
原创flutter3.x+window_manager桌面端os管理系统
flutter3_macOS基于flutter3+window_manager+getx构建客户端os系统程序。
andy2018
2024/04/14
6711
flutter基础布局代码
骨灰级别的基础代码,只是做个简单的记录,方便以后看 都是用dart写的,都在flutter项目下的lib文件夹下 import 'package:flutter/material.dart'; import './tomFont.dart'; void main() { runApp( MaterialApp( theme: ThemeData( primarySwatch: Colors.yellow, ), home: Scaffold(
Tom2Code
2023/02/14
7320
flutter基础布局代码
【Flutter实战】定位装饰权重组件及柱状图案例
第一次鸦片战争,是1840年至1842年英国对中国发动的一场战争,也是中国近代史的开端。闭关锁国后的清朝逐步落后于世界大潮,但在外贸中,一直处于贸易顺差地位。 为了扭转对华贸易逆差,英国开始向中国走私毒品鸦片。1838年冬,道光帝派湖广总督林则徐为钦差大臣,赴广东查禁鸦片。英国政府以此为借口,决定派出远征军侵华,英国国会也通过对华战争的拨款案。
老孟Flutter
2020/09/11
1.4K0
【Flutter实战】定位装饰权重组件及柱状图案例
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Al
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心
卓伊凡
2025/02/04
800
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面
卓伊凡
2025/01/24
1250
Flutter 入门指北之输入处理(登录界面实战)
这边需要提下的是 setState 方法,该方法只有 StatefulWidget 才有,当需要修改某个值的内容的时候,通过该方法进行修改,最后的效果图如下,当输入框文字发生变化的时候,监听的 Text 内容会随之改变,获取内容的 Text 当点击按钮了才发生变化
陈宇明
2020/12/16
2K1
《Flutter个人资料界面应用》
本文我将向您展示如何在 flutter 中制作个人资料页面的 UI,您将学习如何制作圆形按钮以及如何在 flutter 中制作渐变色。
徐建国
2021/08/03
1K0
推荐阅读
Flutter 创建一个很酷的 Booking App UI
6050
【10】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时
2390
Flutter 实现登录 UI
8520
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时
780
2025实战-Flutter3.27仿携程app实例|flutter3.x酒店预订
1530
Flutter 黏贴卡动画效果
2.3K0
flutter制作具有自定义导航栏的渐进式 Web 应用程序
3.1K0
【Flutter 专题】117 图解 Dismissible 滑动清除 Widget
1.3K0
flutter3_window_chat仿微信桌面端聊天实战
7910
自研flutter3.x实战仿抖音app短视频直播FlutterLive
1.1K0
【Flutter】Flutter 布局组件 ( PhysicalModel 组件 )
1.4K0
本文主要介绍flutter聊天应用程序
7550
【Flutter 专题】124 日常问题小结 (三) 自定义 Dialog 二三事
1.2K0
原创flutter3.x+window_manager桌面端os管理系统
6711
flutter基础布局代码
7320
【Flutter实战】定位装饰权重组件及柱状图案例
1.4K0
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Al
800
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为
1250
Flutter 入门指北之输入处理(登录界面实战)
2K1
《Flutter个人资料界面应用》
1K0
相关推荐
Flutter 创建一个很酷的 Booking App UI
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档