一个高颜值Flutter版WanAndroid客户端
1. 前言
❝项目地址: https://github.com/xfhy/WanAndroid-Flutter
❞
前段时间抽了点业余时间学了点Flutter入门,打算写个简单项目练练手.说实话,只有真正动手写东西才能真正切身感受到Flutter的魅力,刚开始学的时候写布局特别难受,各种嵌套,很烦. 后面多写一点儿之后感觉也还是勉强可以接受,各种Widget操作起来也还是容易.
Flutter目前我认为是最合理的跨平台方案,只需要native提供画布,Flutter直接自己在上面画Widget,就单凭这一点就和RN截然不同.RN还需要JS和Java进行中转,多了一层,肯定会慢很多,而且还不能自己画.
再来说说开发和发布,支持JIT和AOT.平时开发使用JIT,可以快速热加载,及时将代码变动传递给flutter app,这其实可以大大提升开发效率.及时查看UI和逻辑是否正确,不像原生开发还需要重新编译,花费很多时间.然后Flutter在发布(release包)的时候,采用AOT,运行时直接指向Native(arm)代码,高效.
可能有时候Flutter需要和native通信,比如使用相机之类的,这时会使用到channel技术,但是这个是C++层次的,性能好.
所以,了解一下Flutter.
2. 下载试玩
扫描二维码下载
3. 技术点
- 封装 上拉加载,下拉刷新
- dio进行网络请求,统一封装get,post
- 封装banner
- Future
- 路由,跳转界面
- 事件总线 event_bus
- toast
- SharedPreference
- ....
4. 项目截图
5. 遇到的问题
5.1 引入第三方库
- 首先去官网package搜索.
- 找到相应插件,点进详情,切换到Installing tab,然后在pubspec.yaml中引入该插件.
- 在本项目控制台,输入flutter pub get. 即引入三方库完成.
5.2 loading
当页面正在loading时,需要一个Widget来占位,不然Widget为空要报错.
5.3 运行在iOS上
- 首先得安装Xcode(7.8G)
- 然后安装 cocoapods
sudo gem install cocoapods
- 然后在ios工程下,执行
pod install
,引入那些依赖 - 然后用AS打开ios项目里面的Info.plist,点击右上角的用Xcode打开.
- 编辑Podfile,将顶部的
platform :ios, '9.0'
注释放开 - 运行到模拟器上.
5.4 如何快速解析json
❝Flutter不支持运行时反射,所以没有像Gson这样自动解析JSON的库来降低解析成本.在Flutter中解析JSON需要完全手动进行操作,麻烦.
❞
可以在AS上装FlutterJsonBeanFactory这个插件,然后右键New->JsonToDartBeanAction,输入文件名和json数据.即可自动生成bean对象,和它所对应的解析代码.
原理是它生成了一个JsonConvert,然后这里面可以根据运行时type去选择应该解析哪一个类对象. 然后bean类在声明的时候是混入了JsonConvert的,可以直接使用JsonConvert里面的方法,完美.
5.5 Flutter ScrollView (滚动视图)
ScrollView是一个带有滚动的视图组件,它本身由三部分组成
- Scrollable - 它监听各种用户手势并实现滚动的交互设计。
- Viewport - 它通过在滚动视图内仅显示一部分小部件来实现滚动的可视化设计。
- Slider - 它们是可以组合以创建各种滚动效果的小部件,如列表,网格和扩展标题。
Scroll是一个抽象类,通常使用CustomScrollView
CustomScrollView( shrinkWrap: true, // 内容 slivers: <Widget>[ new SliverPadding( padding: const EdgeInsets.all(20.0), sliver: new SliverList( delegate: new SliverChildListDelegate( <Widget>[ const Text('A'), const Text('B'), const Text('C'), const Text('D'), ], ), ), ), ],)
5.6 处理Text超出问题
可以放Row或Column中,用Expanded包起来,然后用maxLines控制行数,用overflow: TextOverflow.ellipsis,
控制超出部分的展示.
5.7 让一个ListView支持下拉刷新
非常简单, 使用官方自带的RefreshIndicator即可,将listview放child,然后实现一个_pullToRefresh下拉刷新时调用的方法(做下拉刷新的逻辑).
RefreshIndicator( child: listView, onRefresh: _pullToRefresh, );Future<void> _pullToRefresh() { loadData(); //这里Feature不能返回 null return Future(() => LogUtil.d("lalala")); }
5.8 获取屏幕宽度,高度
MediaQuery.of(context).size.width,MediaQuery.of(context).size.height
5.9 封装通用标题栏
标题栏,每个界面都需要,所以封装一个,取需.
///get通用状态栏static AppBar getCommonAppBar(BuildContext context, String title, {double fontSize, List<Widget> actions}) {if (title == null) { title = "";}return AppBar( leading: IconButton( icon: Icon( Icons.arrow_back, color: Colors.white, ), //点击返回 onPressed: () { if (context != null) { Navigator.pop(context); } }, ), title: Text( title, style: TextStyle( color: Colors.white, fontSize: fontSize == null ? 18.0 : fontSize, ), ), //标题栏居中 centerTitle: true, //右边的action 按钮 actions: actions == null ? <Widget>[] : actions,);}
5.10 格式化String
dart中格式化String,需要引入三方库sprintf
,使用方式如下:
sprintf("lg/collect/%s/json", [15615]);
5.11 获取Android/iOS本地目录
需要引入三方库path_provider
,用于查找文件系统上的常用位置,支持Android和iOS.免得去写一原生代码,这个三方库帮我们封装好了.
Directory tempDir = await getTemporaryDirectory();String tempPath = tempDir.path;Directory appDocDir = await getApplicationDocumentsDirectory();String appDocPath = appDocDir.path;
5.12 展示一个Dialog
以下方法是dart的material包下面的方法.
//展示对话框showDialog( context: context, barrierDismissible: false, builder: (_) { return SpinKitFadingCircle( color: AppColors.colorPrimary, ); });//取消对话框Navigator.of(context).pop();
5.13 间距的简单方式
可以用Padding和margin来实现.其实还有一种方式,可以在Column和Row中快速增加一段间距,利用SizedBox,类似Android中的Space
SizedBox(width: 10.0),
5.14 收起软键盘
有时候需要在点击某些按钮时收起软键盘
FocusScope.of(context).requestFocus(FocusNode());
5.15 让ListView的item点击时有水波纹效果
用InkWell把Item包起来
转载自:https://juejin.cn/post/6844904121179324424