東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

Flutter学习之复制粘贴运行

2021年12月30日星期四



flutter的设计,到处透漏着啰里啰嗦老太太的气息。。。。


1,忽略低龄lint

跟成熟的语言真是没法比。。。。

lint配置文件为 analysis_options.yaml,在项目根目录

默认为:

# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
include: package:flutter_lints/flutter.yaml

linter:
  
  rules:
    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule


1)Use key in widget constructors. (Documentation)

新建一个类,没有给他加带key的构造函数时,会报这个

class Test10BannerDemo extends StatefulWidget {
  //const Test10BannerDemo({Key? key}) : super(key: key);
}

在rules中,增加

use_key_in_widget_constructors: false

类就不提示了,但是,调用的地方之前是以

const Test10BannerDemo()

调用的,没有了Key构造函数,就提示

The constructor being called isn't a const constructor. (Documentation)  Try removing 'const' from the constructor invocation.

也就是说,构造函数没有了Key,就不能用const关键字创建了。。。。

这可以,默认lint到处提示让价const,太恶心了。。。。


2)Prefer const with constant constructors. (Documentation)

到处让加const,因为这个lint....

在rule中,增加

prefer_const_constructors : false

之后就不到处提示让加const了,看着舒服多了。。。。


3) Prefer const literals as parameters of constructors on @immutable classes. (Documentation)

看起来是定义了一个数组,不加const就提示这个

在rule中增加

prefer_const_literals_to_create_immutables: false

保存即可


4)小结

加上这三个,目前代码看起来舒服多了。。。。

include: package:flutter_lints/flutter.yaml

linter:
  
  rules:
    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule
    use_key_in_widget_constructors: false #不提示类创建带Key的构造函数
    prefer_const_constructors: false #不提示让加const
    prefer_const_literals_to_create_immutables: false #数组不提示让加const



2,The argument type 'double?' can't be assigned to the parameter type 'double'. (Documentation)

来源

selectedFontSize: textTheme.caption.fontSize,

是caption可能为空

修改为

selectedFontSize: textTheme.caption?.fontSize ?? 10


3,读取本地图片

1)创建目录

SENRSL:hello senrsl$ tree assets/
assets/
├── images
│   └── bg2021.png
└── music

2 directories, 1 file
SENRSL:hello senrsl$

2)修改pubspec.yaml

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    #   - images/a_dot_burr.jpeg
    #   - images/a_dot_ham.jpeg
    - assets/images/  #加载images目录下(不含子目录)所有图片

放开注释,加目录。。。。

assets是一个集合,如果没有加前面的-,会 报错 Expected "assets" to be a list, but got assets/images/ (String).

3)调用

child: Image.asset('assets/images/bg2021.png'),

4)多平台

理论上来说,在Android手机跟iPhone手机上、mac等电脑上,同一张图片分辨率应该是大不相同的。

但是flutter只提供了1.0倍,2.0倍像素比率的选项。。。。

按照官方的介绍,增加了2.0x和3.0x的目录,其中1.0x是根目录,也就是基准

SENRSL:hello senrsl$ tree assets/
assets/
├── images
│   ├── 2.0x
│   │   └── bg2021.png
│   ├── 3.0x
│   │   └── bg2021.png
│   └── bg2021.png
└── music

4 directories, 3 files
SENRSL:hello senrsl$

然后测试了下,在macbook pro Chrome上使用的是2.0x的图片,在pixel4上使用的竟然是3.0x的图片。。。。

另外,没有修改pubspec.yaml文件增加2.0x和3.0x的目录,看起来是可以自动识别了。。。。


4,Scaffold.of() called with a context that does not contain a Scaffold

里面调用了Scaffold.of(context).showBottomSheet<void>(),但树形结构里没有Scaffold控件

外面包一层Scaffold控件。。。。

class Test10BottomSheetWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Test10PersistentBottomSheetDemo(),
    );
  }
}


5, Error: The argument type 'Route<String> Function(BuildContext, Object)' can't be assigned to the parameter type 'Route<Object?> Function(BuildContext, Object?)' because 'Object?' is nullable and 'Object' isn't

查了一遭,应该是新版本默认开启了空安全,但是sdk跟旧的源码里没开,大部分是能改的,但是小部分更改难度变大。

在不好改的dart文件,使用低版本sdk

// @dart=2.9
// 必须在dart文件的第一行,可以加在任何dart文件中

// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';

指定之后,新的语法方式就不能用了,如  ?、!、required 以及 late 。

此时,编译器不报错了,但是运行报错

Error: A library can't opt out of null safety by default, when using sound null safety.

然后需要在main入口的dart文件,也加上

// @dart=2.9

然后,项目就变成了混合版本的程序,即非健全的空安全。。。。


6,Flutter 多平台支持

默认建的项目,支持 Android、iOS,Web。

怎么让它同时支持 Window、Linux、Mac呢?

1)启用桌面平台支持

SENRSL:hello senrsl$ flutter config --enable-windows-desktop
Setting "enable-windows-desktop" value to "true".

You may need to restart any open editors for them to read new settings.
SENRSL:hello senrsl$ flutter config --enable-macos-desktop
Setting "enable-macos-desktop" value to "true".

You may need to restart any open editors for them to read new settings.
SENRSL:hello senrsl$ flutter config --enable-linux-desktop
Setting "enable-linux-desktop" value to "true".

You may need to restart any open editors for them to read new settings.


2)检查是否成功

SENRSL:hello senrsl$ flutter devices
3 connected devices:

Pixel 4 (mobile) • 99111FFAZ0042Q • android-arm64  • Android 12 (API 31)
macOS (desktop)  • macos          • darwin-x64     • macOS 12.0.1 21A559 darwin-x64
Chrome (web)     • chrome         • web-javascript • Google Chrome 96.0.4664.110
SENRSL:hello senrsl$

可以看到设备列表里多了macos....

3)运行在桌面设备上

这时候打开旧的项目,可用设备里有了macos,但是运行会提示

Exception: No macOS desktop project configured。

按照文档说法,这时候flutter create新项目,就会自带 window、linux、macos的设备运行目录了。

4)旧项目增加 桌面平台运行配置

SENRSL:hello senrsl$ flutter create --platforms=windows,macos,linux .
Recreating project ....
  windows/runner/flutter_window.cpp (created)
  windows/runner/utils.h (created)
  windows/runner/utils.cpp (created)
  windows/runner/runner.exe.manifest (created)
  windows/runner/CMakeLists.txt (created)
  windows/runner/win32_window.h (created)
  windows/runner/Runner.rc (created)
  windows/runner/win32_window.cpp (created)
  windows/runner/resources/app_icon.ico (created)
  windows/runner/main.cpp (created)
  windows/runner/resource.h (created)
  windows/runner/flutter_window.h (created)
  windows/flutter/CMakeLists.txt (created)
  windows/.gitignore (created)
  windows/CMakeLists.txt (created)
  macos/Runner.xcworkspace/contents.xcworkspacedata (created)
  macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (created)
  macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png (created)
  macos/Runner/DebugProfile.entitlements (created)
  macos/Runner/Base.lproj/MainMenu.xib (created)
  macos/Runner/MainFlutterWindow.swift (created)
  macos/Runner/Configs/Debug.xcconfig (created)
  macos/Runner/Configs/Release.xcconfig (created)
  macos/Runner/Configs/Warnings.xcconfig (created)
  macos/Runner/Configs/AppInfo.xcconfig (created)
  macos/Runner/AppDelegate.swift (created)
  macos/Runner/Info.plist (created)
  macos/Runner/Release.entitlements (created)
  macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (created)
  macos/Runner.xcodeproj/project.pbxproj (created)
  macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (created)
  macos/Flutter/Flutter-Debug.xcconfig (created)
  macos/Flutter/Flutter-Release.xcconfig (created)
  macos/.gitignore (created)
  linux/main.cc (created)
  linux/my_application.h (created)
  linux/my_application.cc (created)
  linux/flutter/CMakeLists.txt (created)
  linux/.gitignore (created)
  linux/CMakeLists.txt (created)
Running "flutter pub get" in hello...                               8.8s
Wrote 47 files.

All done!
In order to run your application, type:

  $ cd .
  $ flutter run

Your application code is in ./lib/main.dart.

SENRSL:hello senrsl$

这时,再看项目,根目录增加了windows、Linux、macos的项目了,跟ios和Android平级。

这时候,再打开IDE,运行macos,就成功了。。。。。

此处配图1



这个多平台兼容可以。。。。。

7,网络请求

查了一遭,就三个,dart自带的httpClient、官网的http、还有flutterchina club的dio。。。。

1)HttpClient

先从眼熟的开始

2)http lib


8,RenderBox was not laid out: RenderPointerListener

之前Row[Text(),TextField(),]

这个错误是说,TextField控件需要有宽度限制。。。。

所以给他一个可以识别的宽度才行,如 TextFiled()铺满剩下的控件,

修改后,变成了

Row[Text(),Expanded(TextFiled())]


9, Avoid `print` calls in production code. (Documentation)

print()换成 debugPrint();


10, 组件间传值

如果有两个组件,比如一个 RadioButton,一个按钮,他俩是平行的,那么如何在点击按钮的时候获取radioButton的值呢?

查了一上午,竟然是用回调。。。。

一般的回调有  VoidCallback, Function(x), Valuechanged<T>, Valuesetter<T>。。。。。

11,Unsupported operation: Platform._version

web端不支持 dart.io 库  github.com/flutter/flutter/issues/39998

mobile 跟 desktop可以。。。。

12,原生通信

此处配图2



通信的三个方法

  1. MethodChannel:Flutter 与 Native 端相互调用,调用后可以返回结果,可以 Native 端主动调用,也可以Flutter主动调用,属于双向通信。此方式为最常用的方式, Native 端调用需要在主线程中执行。
  2. BasicMessageChannel:用于使用指定的编解码器对消息进行编码和解码,属于双向通信,可以 Native 端主动调用,也可以Flutter主动调用。
  3. EventChannel:用于数据流(event streams)的通信, Native 端主动发送数据给 Flutter,通常用于状态的监听,比如网络变化、传感器数据等。


啰里啰嗦。。。。

--
senRsl
2021年12月16日10:34:43

没有评论 :

发表评论