0%

Flutter最佳实践整理

Text 以字符的方式截断

https://github.com/flutter/flutter/issues/52869

在flutter中,Text控件默认的溢出显示模式是TextOverflow.fade ,就是淡出

在iOS或者Android平台默认的文件截断模式一般是…省略,flutter里面对应的截断模式为TextOverflow.ellipsis ,不过这里的截断是英文按照单词来的,这样的模式会导致如果最后一个单词很长时,截断显示会整理省略而不是最后超出的字符省略,导致模块可能有一大块空白。

Dart系统定义的截断模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// How overflowing text should be handled.
///
/// A [TextOverflow] can be passed to [Text] and [RichText] via their
/// [Text.overflow] and [RichText.overflow] properties respectively.
enum TextOverflow {
/// Clip the overflowing text to fix its container.
clip,

/// Fade the overflowing text to transparent.
fade,

/// Use an ellipsis to indicate that the text has overflowed.
ellipsis,

/// Render overflowing text outside of its container.
visible,
}

如何解决英文单词被整体截断呢?

将单词的每个字符切割开,插入宽度0的占位字符,打破系统默认的机制,这样就可以以字符为单位省略了

需要注意。这种方式相当于修改了文本的内容,一般文本最大一行显示可以用,如果文本支持2行以及以上的显示的话,将会导致换行不再按照字符进行而按照单词进行

下面是Example实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
extension TextOverflowUtil on String {
/// 将flutter系统默认的单词截断模式转换成字符截断模式
/// 通过向文本中插入宽度为0的空格实现
static String toCharacterBreakStr(String word) {
if (word == null || word.isEmpty) {
return word;
}
String breakWord = '';
word.runes.forEach((element) {
breakWord += String.fromCharCode(element);
breakWord += '\u200B';
});
return breakWord;
}
}

文本划线

通过Text的decoration属性来实现划线

  • TextDecoration.none 没有
  • TextDecoration.underline 下划线
  • TextDecoration.overline 上划线
  • TextDecoration.lineThrough 中间的线(删除线)

// 划线相关的属性设置
decorationColor decoration划线的颜色
decorationStyle decoration划线的样式

  • TextDecorationStyle.solid 实线
  • TextDecorationStyle.double 画两条线
  • TextDecorationStyle.dotted 点线(一个点一个点的)
  • TextDecorationStyle.dashed 虚线(一个长方形一个长方形的线)
  • TextDecorationStyle.wavy 正玄曲

效果图如下

best_practise_01

VS Code实现保存时自动代码格式化

VS Code中代码格式化默认快捷键:【Shift】+【Alt】+ F

实现手动保存(Ctril + S)时自动触发代码格式化:

1)Code → Perference → Settting 点击右上角(Open Setting(JSON) )

best_practise_02

2)在settings.json下的【工作区设置】中添加以下语句:

1
2
"editor.formatOnType": true,
"editor.formatOnSave": true

best_practise_03

解决 setState() called after diapose()

网络请求成功前退出了页面,该 State 被从对象树卸载掉,而这时回调了网络请求的方法,方法中带有 setState 的调用,也就导致了该问题。

1
2
3
4
5
if (mounted) {
setState(() {
this._books = dataModel.books;
});
}

Waiting for another flutter command to release the startup lock…等待另一个flutter命令释放启动锁

  1. 退出 VS Code。
  2. 打开 flutter 安装目录 如:…\flutter\flutter\bin\cache 删除里面的 lockfile。
  3. 重启打开VS Code。

原因:当你的项目异常关闭,下次启动就会出现上面的一行话,
此时需要打开 flutter/bin/cache/lockfile,删除就行了,
或者直接用下面的命令:rm ./flutter/bin/cache/lockfile。

在Stateless控件内部或者浮层内部刷新,可以使用StatefullBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
showDialog<void>(
context: context,
builder: (BuildContext context) {
int selectedRadio = 0;
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int value) {
setState(() => selectedRadio = value);
},
);
}),
);
},
),
);
},
);

这里通过selectedRadio变量记录Radio的是否选中的状态

平台相关的判断

只关心是否是iOS和Android的情况下不需要依赖context,优先使用Platform

1
2
Platform.isAndroid
Platform.isIOS

需要详细知道具体哪个平台才使用TargetPlatform

这个API的缺点是需要依赖context这个参数

1
2
3
4
5
6
7
final platform = Theme.of(context).platform;

if (platform == TargetPlatform.android) {
...
} else if (platform == TargetPlatform.iOS) {
...
}

ScrollView 滑动隐藏键盘

https://stackoverflow.com/questions/55306855/hide-keyboard-on-scroll-in-flutter

使用ScrollView的keyboardDismissBehavior属性

1
2
3
ListView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag
)

回调写法

a.无参数回调

VoidCallback

b.有一个参数回调

ValueChanged

c.参数大于一个

可以通过typedef自定义一个函数

下面是Example用法

1
2
3
final VoidCallback onPressed;
final ValueChanged<T> onSelectHandler;
typedef ImageSwiperOnTap = void Function(int index, List<String> imgUrls);

flutter pub get is stuck

可以通过切换flutter镜像到中文站点来解决

使用系统shell,请编辑

使用oh_my_zsh, 需要编辑.zshrc

1
2
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

保存文件后,关闭,下次重新打开终端生效

再执行flutter pub get 查看速度是否正常