| 欢迎、引导 | 登录、注册 | 主页 |
|---|---|---|
![]() |
![]() |
![]() |
环境搭建
可以参考 https://flutter.cn/docs/get-started/install/macos 搭建
Flutter 使用到的语言为 Dart
Dart 语言学习可以看 https://gitee.com/shizidada/dart-learn
创建项目
// --org com.moose.plus 创建包名// moose_app 应用名称flutter create --org com.moose.plus moose_app
moose_app
目录介绍
├── android // android 平台运行代码│ ├── ...├── ios // ios 平台运行代码│ ├── ...├── lib // flutter 平台运行代码│ ├── main.dart // 主入口文件├── test // 测试│ ├── ...├── web // web 平台│ ├── ...└── pubspec.yaml // flutter 运行依赖└── ...
开始搭建 Flutter 项目运行脚手架
代码目录
- 在 lib 目录下创建 core 目录,与 UI 无关到逻辑代码
- 在 lib 目录下创建 ui 目录,UI 展示视图代码
├── lib│ ├── core│ ├── ui
修改 main.dart
import 'dart:io';import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'app.dart';void main() {// 主入口运行 --> 主要代码 --> app.dartrunApp(ATHApp());// android 平台 statusBar 沉浸式if (Platform.isAndroid) {SystemUiOverlayStyle systemUiOverlayStyle =SystemUiOverlayStyle(statusBarColor: Colors.transparent);SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);}}
添加项目所需依赖
- 国内镜像,访问速度快 https://pub.flutter-io.cn/
dependencies:flutter:sdk: flutter# 构建路由模块fluro: ^2.0.3# svg 图片显示, flutter_svg 新版本存在问题,使用临时修复版本,取从 github 上分支,后面换 release 版本flutter_svg:git:url: git://github.com/gskinnerTeam/flutter_svg.gitref: 12b55b464d2e253f411a17798527a7daa2c00ceb# 屏幕适配 新版本使用和其他版本有区别flutter_screenutil: ^4.0.3+3# 轮播图flutter_swiper: ^1.1.6shared_preferences: ^2.0.4
创建 app.dart,主要运行界面
import 'package:flutter/material.dart';class ATHApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return buildApp(context);}Widget buildApp(BuildContext context) {return MaterialApp(// 应用在后台挂起时显示标题title: 'Moose Flutter Learn',// 修改全局 app 样式theme: Theme.of(context).copyWith(appBarTheme: Theme.of(context).appBarTheme.copyWith(color: kPrimaryColor,elevation: 0,brightness: Brightness.light,)),// 不现实 debug 标签debugShowCheckedModeBanner: false,// 主页home: ATHSplashScreen());}}
应用欢迎界面
...class ATHSplashScreen extends StatelessWidget {static final String routeName = "app://splash";@overrideWidget build(BuildContext context) {return Scaffold(body: ATHSplashBody(),);}}....
ATHSplashBody
- 显示一张图片 —> 可能广告
- 倒计时结束或者点击进入 app
class ATHSplashBody extends StatefulWidget {@override_ATHSplashBodyState createState() => _ATHSplashBodyState();}class _ATHSplashBodyState extends State<ATHSplashBody> {Timer _timer;int _count = 5;@overridevoid initState() {super.initState();_startTime();}@overrideWidget build(BuildContext context) {return Stack(children: <Widget>[ConstrainedBox(constraints: BoxConstraints.expand(),child: Image.asset("assets/images/welcome.png", fit: BoxFit.fill),),Positioned(top: 60,right: 40,child: ClipRRect(borderRadius: BorderRadius.all(Radius.circular(8.w)),child: GestureDetector(onTap: () {_navigationPage();},child: Container(color: Colors.black12.withAlpha(200),width: 180.w,height: 50.h,alignment: Alignment.center,child: Text("跳过广告 $_count",style: TextStyle(color: Colors.white),),),),),),],);}_startTime() async {var _duration = Duration(seconds: 1);Timer(_duration, () {// 空等1秒之后再计时_timer = Timer.periodic(const Duration(milliseconds: 1000), (v) {_count--;if (_count <= 0) {if (_timer != null) _timer.cancel();_navigationPage();} else {setState(() {});}});return _timer;});}void _navigationPage() async {_timer.cancel();// 需要判断是否为第一次进入 appATHNavigator.pushFromRight(context, ATHGuideScreen.routeName);}}
构建fluro 路由架子
Flutter 可以使用自带的 router‘s,使用 fluro 方便维护管理路由
├── lib│ ├── core│ ├── ui│ ├──├── routers│ ├──├──├── application.dart│ ├──├──├── route_handlers.dart│ ├──├──├── routers.dart
application.dart 定义
- 维护 FluroRouter(其他版本 Router),用于页面跳转
import 'package:fluro/fluro.dart';class ATHApplication {static FluroRouter router;}
route_handlers.dart 定义
- 栗子见代码
- 定义每一个显示的页面
import 'package:fluro/fluro.dart';import 'package:flutter/material.dart';Handler splashHandler = Handler(handlerFunc: (BuildContext context, Map<String, List<String>> params) {return ATHSplashScreen();});Handler guideHandler = Handler(handlerFunc: (BuildContext context, Map<String, List<String>> params) {return ATHGuideScreen();});
routers.dart 定义具体路由跳转规则
import 'package:fluro/fluro.dart';import 'route_handlers.dart';class ATHRoutes {static void configureRoutes(FluroRouter router) {router.define(ATHSplashScreen.routeName, handler: splashHandler);router.define(ATHGuideScreen.routeName, handler: guideHandler);}}
使用定义的路由
- 修改 app.dart
- 初始化 FluroRouter
....ATHApp({Key key}) : super(key: key) {final router = FluroRouter();ATHRoutes.configureRoutes(router);ATHApplication.router = router;}....Widget buildApp() {home: ATHSplashScreen(),// 添加挂在到 app 上onGenerateRoute: ATHApplication.router.generator}....
屏幕适配
- 可以获取屏幕像素转换为设计稿对应的尺寸
- 使用
flutter_screenutil: ^4.0.3+3模块简化操作
使用 flutter_screenutil
- pubspec.yaml 添加 flutter_screenutil 依赖
- 修改 app.dart
@overrideWidget build(BuildContext context) {// ScreenUtilInit 为 flutter_screenutil 提供 APIreturn ScreenUtilInit(// 默认设计稿尺寸designSize: Size(750, 1334),// 设置是否根据系统字体大小allowFontScaling: false,builder: () => buildApp(context));}
- 在后面使用直接可以使用
栗子
ScreenUtil().setWidth(540) (sdk>=2.6 : 540.w) //根据屏幕宽度适配尺寸
ScreenUtil().setHeight(200) (sdk>=2.6 : 200.h) //根据屏幕高度适配尺寸(一般根据宽度适配即可)
ScreenUtil().radius(200) (sdk>=2.6 : 200.r) //根据宽度或高度中的较小者进行调整
ScreenUtil().setSp(24) (sdk>=2.6 : 24.sp) //适配字体
根据 API 参考 https://github.com/OpenFlutter/flutter_screenutil/blob/master/README_CN.md
应用引导界面
使用 flutter_swiper
- 最后一张引导图显示跳转按钮
class ATHGuideScreen extends StatefulWidget {static final String routeName = "app://guide";@override_ATHGuideScreenState createState() => _ATHGuideScreenState();}class _ATHGuideScreenState extends State<ATHGuideScreen> {List<String> guideImages = ['assets/images/guide-1.jpeg','assets/images/guide-2.jpeg',];void _handleCheck() async {ATHNavigator.pushReplace(context, ATHWelcomeScreen.routeName,clearStack: true);}@overrideWidget build(BuildContext context) {return Scaffold(body: Swiper(itemCount: guideImages.length,itemBuilder: (BuildContext context, int position) {String imagePath = guideImages[position];return Stack(fit: StackFit.passthrough,alignment: Alignment.center,children: [Image.asset(imagePath, fit: BoxFit.cover),position == guideImages.length - 1? Positioned(bottom: 100.h,child: TextButton(onPressed: () {_handleCheck();},style: ButtonStyle(padding: MaterialStateProperty.all(EdgeInsets.symmetric(vertical: 16.h, horizontal: 32.w)),backgroundColor:MaterialStateProperty.all(Colors.white)),child: Text("立即体验",style: TextStyle(color: Colors.black),),),): SizedBox()],);},// 设置页码pagination: SwiperPagination(alignment: Alignment.bottomCenter,builder: DotSwiperPaginationBuilder(color: Colors.black54, activeColor: Colors.white)),loop: false,scrollDirection: Axis.horizontal,),);}}



