flutter-开发记录(错误或技巧)

错误

  1. flutter doctor 显示:
    1
    Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

方案一:
根据提示运行flutter doctor –android-licenses 一路y就好了。

  1. Row中包含TextField时在弹出软键盘时会overflow(TextField inside of Row causes layout exception: Unable to calculate size)

解决:在TextField外层在包一个Flexible组件即可;

参考:https://stackoverflow.com/questions/45986093/textfield-inside-of-row-causes-layout-exception-unable-to-calculate-size (译文:(假设您正在使用Row,因为您希望将来在TextField旁边放置其他小部件。)Row小部件想要确定其非灵活子节点的内在大小,以便它知道它为灵活子节点留下了多少空间。 但是,TextField没有固有宽度; 它只知道如何将自身大小调整到其父容器的整个宽度。 尝试将其包装在Flexible或Expanded中,告诉Row您希望TextField占用剩余空间:)

  1. Keyboard overflows TextField creating yellow/black stripes
    文本域获取焦点时,弹出软键盘,导致overflowed错误,
    修正:通过设置Scaffold的属性resizeToAvoidBottomPadding: false即可,

原因:猜测(可能键盘的弹出导致,内容视图的高度+键盘的高度超出了一个屏幕的高度从而产生了overflowed)。

参考网址:https://github.com/flutter/flutter/issues/13339 (译文:当你点击文本字段键盘显示白色内容溢出整个脚手架区域时,是的还有同样的问题。 使用resizeToAvoidBottomPadding它确实有效但我认为禁用此选项键盘不会尊重焦点文本字段,也不会将内容滚动到适当的焦点框

  1. 使用cipher时报如下错误:
    1
    The parameter 'm' of the method 'BigIntegerV8::modPowInt' has type bignum::BigIntegerV8, which does not match the corresponding type in the overridden method (dynamic).

这个时我在使用依赖cipher: ^0.7.1时遇到的,后来查看Dart版本,和cipher的发布日志发现,cipher: ^0.7.1只使用与Dart 1,而开发当前用的时Dart 2,因此出现该错误,加密/解密依赖目前开发用的是 crypto.

技巧

!!! 谨记:Flutter 中是基于数据驱动,Java中是基于事件驱动。

  1. Dart中字符串转换为字节数组或列表(How do I convert a UTF-8 String into an array of bytes in Dart?)

代码如下:

1
2
3
import 'dart:convert';
List<int> bytes = utf8.encode("Some data"); //UTF8 is deprecated sind Dart 2. But it was just renamed to utf8: List<int> bytes = utf8.encode("Some data");
print(bytes) //[115, 111, 109, 101, 32, 100, 97, 116, 97]

参考:https://stackoverflow.com/questions/10404147/how-do-i-convert-a-utf-8-string-into-an-array-of-bytes-in-dart

  1. Dart json操作:
    在Dart中json的构建和将对象转换为json字符很简单,麻烦在将json转换为一个对象,关于json的操作依赖于dart:convert;
  • 构建一个json字符串:

    1
    2
    3
    4
    {
    "name": "John Smith",
    "email": "john@example.com"
    }
  • 将对象转换为一个字符串

1
String json = json.encode(user);
  • 序列化json对象:

    • 序列化JSON内联

      1
      2
      3
      Map<String, dynamic> user = json.decode(json);
      print('Howdy, ${user['name']}!');
      print('We sent the verification link to ${user['email']}.');

      通过上面我们知道,json.decode()只返回一个Map ,这意味着我们直到运行时才知道值的类型。 使用这种方法,我们失去了大多数静态类型语言功能:类型安全,自动完成以及最重要的编译时异常。 我们的代码可能会立即变得更容易出错。
      例如,每当我们访问名称或电子邮件字段时,我们都会很快引入拼写错误。 由于我们的整个JSON仅存在于地图结构中,因此我们的编译器不知道这是一个错字。

    • 在模型类中序列化JSON

      我们可以通过引入一个普通的模型类来解决前面提到的问题,我们称之为User。 在User类中,我们有:
      User.fromJson构造函数,用于从地图结构构造新的User实例
      一个toJson方法,它将User实例转换为map。
      这样,调用代码现在可以具有类型安全性,名称和电子邮件字段的自动完成以及编译时异常。 如果我们使用拼写错误或将字段视为int而不是字符串,我们的应用程序甚至不会编译,而不是在运行时崩溃。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      class User {
      final String name;
      final String email;

      User(this.name, this.email);

      User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
      email = json['email'];

      Map<String, dynamic> toJson() =>
      {
      'name': name,
      'email': email,
      };
      }

      现在,序列化逻辑的责任在模型本身内部移动。 通过这种新方法,我们可以非常轻松地反序列化用户。

      1
      2
      3
      4
      5
      Map userMap = json.decode(json);
      var user = new User.fromJson(userMap);

      print('Howdy, ${user.name}!');
      print('We sent the verification link to ${user.email}.');

参考地址:

  1. Flutter中获取设备信息:

依赖于 import ‘dart:io’;和 device_info : ^0.2.0;

1
2
3
4
5
6
7
8
9
10
DeviceInfoPlugin deviceInfo = new DeviceInfoPlugin();
if(Platform.isIOS){
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
print('Running on ${iosInfo.utsname.machine}'); // e.g. "iPod7,1"
//ios相关代码
}else if(Platform.isAndroid){
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
print('Running on ${androidInfo.model}'); // e.g. "Moto G (4)"
//android相关代码
}

参考地址:

  1. Flutter加载本地资源

通过异步加载本地Json资源,需要先在pubspec.yaml文件添加资源文件,然后再通过异步加载资源文件,以下为实例:

1
2
3
4
5
6
7
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
assets:
- assets/config.json //资源所在位置

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'dart:convert';
import 'dart:async' show Future;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
void _loadJson() {
loadAsset().then((value){
JsonDecoder decoder = new JsonDecoder();
List<List<String>> json = decoder.convert(value);
print('姓名:'+json[0][0]+',年龄:'+json[0][1]);
});
}

参考地址: