一个高颜值Flutter版WanAndroid客户端

1. 前言

项目地址: https://github.com/xfhy/WanAndroid-Flutterios

前段时间抽了点业余时间学了点Flutter入门,打算写个简单项目练练手.说实话,只有真正动手写东西才能真正切身感觉到Flutter的魅力,刚开始学的时候写布局特别难受,各类嵌套,很烦. 后面多写一点儿以后感受也仍是勉强能够接受,各类Widget操做起来也仍是容易.git

Flutter目前我认为是最合理的跨平台方案,只须要native提供画布,Flutter直接本身在上面画Widget,就单凭这一点就和RN大相径庭.RN还须要JS和Java进行中转,多了一层,确定会慢不少,并且还不能本身画.github

再来讲说开发和发布,支持JIT和AOT.平时开发使用JIT,能够快速热加载,及时将代码变更传递给flutter app,这其实能够大大提高开发效率.及时查看UI和逻辑是否正确,不像原生开发还须要从新编译,花费不少时间.而后Flutter在发布(release包)的时候,采用AOT,运行时直接指向Native(arm)代码,高效.web

可能有时候Flutter须要和native通讯,好比使用相机之类的,这时会使用到channel技术,可是这个是C++层次的,性能好.json

因此,了解一下Flutter.markdown

2. 下载试玩

扫描二维码下载 网络

3. 技术点

  • 封装 上拉加载,下拉刷新
  • dio进行网络请求,统一封装get,post
  • 封装banner
  • Future
  • 路由,跳转界面
  • 事件总线 event_bus
  • toast
  • SharedPreference
  • ....

4. 项目截图

image1 image2 image3 image4 image6 image6

5. 遇到的问题

5.1 引入第三方库

  1. 首先去 官网package搜索.
  2. 找到相应插件,点进详情,切换到Installing tab,而后在pubspec.yaml中引入该插件.
  3. 在本项目控制台,输入flutter pub get. 即引入三方库完成.

5.2 loading

当页面正在loading时,须要一个Widget来占位,否则Widget为空要报错.app

5.3 运行在iOS上

  1. 首先得安装Xcode(7.8G)
  2. 而后安装 cocoapods sudo gem install cocoapods
  3. 而后在ios工程下,执行 pod install,引入那些依赖
  4. 而后用AS打开ios项目里面的Info.plist,点击右上角的用Xcode打开.
  5. 编辑Podfile,将顶部的 platform :ios, '9.0' 注释放开
  6. 运行到模拟器上.

5.4 如何快速解析json

Flutter不支持运行时反射,因此没有像Gson这样自动解析JSON的库来下降解析成本.在Flutter中解析JSON须要彻底手动进行操做,麻烦.编辑器

能够在AS上装FlutterJsonBeanFactory这个插件,而后右键New->JsonToDartBeanAction,输入文件名和json数据.便可自动生成bean对象,和它所对应的解析代码.ide

原理是它生成了一个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包起来

相关文章
相关标签/搜索