November 19, 2022

Flutter 使用报告

Flutter 介绍

Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android 平台。Flutter 提供了丰富的组件、接口,开发者可以很快地为 Flutter 添加 Native 扩展。

在此记录些常用资料:

文档文章
官方网站Flutter 最佳实践和编码准则
官方英文文档iPad 大屏 & Flutter 多引擎适配之路
官方中文文档详解 android:elevation 的使用
官方 Package 站Flutter elevation 属性名称的含义
Flutter 实战Android 中 elevation 的设置方法
模式匹配
工具
Json to Dart图片缓存
BasedWidget
QWeatherIcons

使用 index.dart 文件简化导入

lib/index.dartexport 所有子文件夹下的 index.dart 文件,其 export 该文件夹下非自身的所有 *.dart 文件。

在所有 *.dart 文件,包括 main.dart,内尽绝大可能 import 'package:<项目名>/index.dart'; 即可简化导入。

同时当要引入外部包时,只要在 lib/index.dart 文件内导入即可,当然,有时会出现不同包之间的类名冲突,此时在需要使用到该包的地方单独 import 即可,或者使用 hideshow 语法限制,具体例子如下:

/// 各路由下的 index.dart
export 'main.dart';
export 'pages/index.dart';
export 'widgets/index.dart';
 
/// flutter 相关
/// [RefreshCallback]`export 'package:flutter/material.dart'` 冲突,两者近似
export 'package:flutter/cupertino.dart' hide RefreshCallback;
export 'package:flutter/services.dart'
    show DeviceOrientation, SystemChrome; // 设备服务
/// [Badge]`export 'package:badges/badges.dart'; // 小红点提示` 冲突,我想用外部包
export 'package:flutter/material.dart' hide Badge;
export 'package:flutter/gestures.dart';
 
/// dart 相关
export 'dart:async' show Timer, StreamSubscription;
export 'dart:convert';
export 'dart:io';
export 'dart:ui' show ImageFilter;
 
/// 外部包相关
export 'package:badges/badges.dart'; // 小红点提示
/// [Interval]`package:flutter/src/animation/curves.dart` 冲突,两者结构完全不同,但外部包里的这个用不到
export 'package:dart_date/dart_date.dart' hide Interval; // 日期工具
/// [Text]`export 'package:flutter/material.dart` 冲突,两者结构完全不同,但外部包里的这个用不到
export 'package:flutter_quill/flutter_quill.dart' hide Text; // 富文本

版本号构建问题

Flutter 使用 android/app/build.gradle 来打包 APK, 且其引入了 flutter.gradle 并指向 flutter.groovy

约在 flutter.groovy993 行:

if (shouldSplitPerAbi()) {
    variant.outputs.each { output ->
        def abiVersionCode = ABI_VERSION.get(output.getFilter(OutputFile.ABI))
        if (abiVersionCode != null) {
            output.versionCodeOverride =
                abiVersionCode * 1000 + variant.versionCode
        }
    }
}

我们知道 Flutter 将判断是否使用了 'split-per-abi'Flag, 是则在 ABI_VERSION 选择一个版本 * 1000 再加上构建号。官方解释见 此链接

我们只需修改 ABI_VERSION map 如下:

private static final Map ABI_VERSION = [
    (ARCH_ARM32)        : 0,
    (ARCH_ARM64)        : 0,
    (ARCH_X86)          : 0,
    (ARCH_X86_64)       : 0,
]

注意若进行了 Flutter 版本更新,应重新修改该 flutter.groovy 文件

Vivo 系手机无法调试 Flutter 程序

Vivo 系列手机升至 Origin3 后发现调试 Flutter 应用卡在启动页,并且没有任何报错,详见 Github Issue,简化自 此链接

答案是 Vivo 发大病连日志都隐藏,我们需要提供 IMEI 1 码至 Vivo 官方进行授权

  1. 拨号盘输入 *#06# 复制 IMEI 1
  2. 添加企业 QQ 号 3002261823 或通过 官方网站 联系
  3. 提交相关问题和信息,要求一键授权自己的手机
  4. 等待授权成功后拨号盘输入 *#*#112#*#*右上角按钮 > 更多 > 一键授权 即可

AlertDialogcontent 传入 ListView 时在调试模式下报错

这是个怪问题,release 版本正常运行,解决方法如下:

AlertDialog(
  title: (...),
  content: SizedBox(
    width: double.minPositive, // 可选 double.maxFinite 但建议为 double.minPositive,
    child: ListView(
      shrinkWrap: true,
      children: (...),
    ),
  ),
  contentPadding: (...),
  actions: (...),
);

Ard 语法

详见 此页面

感想

  • Flutter 的使用非常简单,上手也快,非常有意思。
  • 自己用 Flutter 写了很多项目,这里来个 Mercurius 日记软件的 仓库链接