命令行创建 Flutter
使用命令行创建项目:
1
| flutter create --platforms=android,ios D:\flutter_projects\project_name
|
参数 |
说明 |
–project-name |
项目名,全部小写+下划线 |
–platforms |
支持的平台,可选值为:android、ios、windows、linux、macos、web,此参数仅在“–template”设置为应用程序或插件时有效 |
–description |
项目描述,此字符串最终位于pubspec.yaml 文件中,默认为:A new Flutter project. |
–org |
项目的组织,使用反向域名表示法。此字符串用于Java包名称,并作为iOS捆绑包标识符中的前缀,默认为:com.example |
有关该命令的更多信息,参见flutter --help create
。
Android 未开启网络权限
APP开发时正常,build后报错如下:
1
| [ERROR:flutter/lib/ui/http://ui_dart_state.cc(148)] Unhandled Exception: SocketException: Failed host lookup: 'api.douban.com' (OS Error: No address associated with hostname, errno = 7)
|
解决方法:
在android\app\src\main\AndroidManifest.xml
中添加网络权限:
1
| <uses-permission android:name="android.permission.INTERNET" />
|
如:
type ‘(XXX?) => void’ is not a subtype of type ‘((dynamic) => void)?’
试图用StatefulWidget封装DropDownButton时发现问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| class DebugDropdownButton<T> extends StatefulWidget { const DebugDropdownButton({ super.key, required this.dataMap, this.onChanged, this.initItemKey, });
final Map<String, T> dataMap; final String? initItemKey; final ValueChanged<T?>? onChanged;
@override State<DebugDropdownButton> createState() => _DebugDropdownButtonState(); }
class _DebugDropdownButtonState<T> extends State<DebugDropdownButton> { ValueNotifier<T?> valueNotifier = ValueNotifier(null);
List<DropdownMenuItem<T>> createDropdownItemList() { final List<DropdownMenuItem<T>> list = []; for (var entry in widget.dataMap.entries) { list.add(DropdownMenuItem(value: entry.value, child: Text(entry.key))); } return list; }
@override void initState() { super.initState(); if (widget.initItemKey != null) { valueNotifier.value = widget.dataMap[widget.initItemKey!]; } }
@override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: valueNotifier, builder: (context, value, child) => SizedBox( width: 300, child: DropdownButtonHideUnderline( child: DropdownButton<T>( value: value, isExpanded: true, items: createDropdownItemList(), onChanged: (T? v) { valueNotifier.value = v; widget.onChanged?.call(v); }, ), ), ), ); } }
|
使用方法:
1 2 3 4 5 6 7 8 9 10
| return DebugDropdownButton<String>( initItemKey: '正式环境', dataMap: const { '正式环境': '正式环境Url', '测试环境': '测试环境Url', }, onChanged: (String? value) { }, );
|
发现触发onChanged方法时出现异常:

type ‘(String?) => void’ is not a subtype of type ‘((dynamic) => void)?’
解决方法:
有人在Github上提了issue:issue
原先的代码:
1 2 3 4 5 6 7 8 9 10
| class DebugDropdownButton<T> extends StatefulWidget { @override State<DebugDropdownButton> createState() => _DebugDropdownButtonState(); }
class _DebugDropdownButtonState<T> extends State<DebugDropdownButton> { }
|
修改为:
1 2 3 4 5 6 7 8 9 10
| class DebugDropdownButton<T> extends StatefulWidget { @override State<DebugDropdownButton<T>> createState() => _DebugDropdownButtonState(); }
class _DebugDropdownButtonState<T> extends State<DebugDropdownButton<T>> { }
|
参观我的个人网站:http://saoke.fun