1. Text 以字符的方式截断
在 flutter 中,Text 控件默认的溢出显示模式是 TextOverflow.fade
,就是淡出
在 iOS 或者 Android 平台默认的文件截断模式一般是...省略,flutter 里面对应的截断模式为TextOverflow.ellipsis
,不过这里的截断是英文按照单词来的,这样的模式会导致如果最后一个单词很长时,截断显示会整理省略而不是最后超出的字符省略,导致模块可能有一大块空白。
Dart 系统定义的截断模式
/// 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 实现
extension TextOverflowUtil on String {
/// 将flutter系统默认的单词截断模式转换成字符截断模式
/// 通过向文本中插入宽度为0的空格实现
/// https://github.com/flutter/flutter/issues/18761
static String? toCharacterBreakStr(String? word) {
if (word == null || word.isEmpty) {
return word;
}
return Characters(word)
.replaceAll(Characters(''), Characters('\u{200B}'))
.toString();
}
}
2. 文本划线
通过 Text 的 decoration 属性来实现划线
• TextDecoration.none 没有
• TextDecoration.underline 下划线
• TextDecoration.overline 上划线
• TextDecoration.lineThrough 中间的线(删除线)
// 划线相关的属性设置
• decorationColor decoration划线的颜色
• decorationStyle decoration划线的样式
• TextDecorationStyle.solid 实线
• TextDecorationStyle.double 画两条线
• TextDecorationStyle.dotted 点线(一个点一个点的)
• TextDecorationStyle.dashed 虚线(一个长方形一个长方形的线)
• TextDecorationStyle.wavy 正玄曲
效果图如下
3. VS Code 实现保存时自动代码格式化
VS Code中代码格式化默认快捷键:【Shift】+【Alt】+ F
实现手动保存(Ctril + S)时自动触发代码格式化:
1)Code → Perference → Settting 点击右上角(Open Setting(JSON) )
2)在settings.json下的【工作区设置】中添加以下语句:
"editor.formatOnSave": true
4. 解决 setState() called after diapose()
网络请求成功前退出了页面,该 State 被从对象树卸载掉,而这时回调了网络请求的方法,方法中带有 setState 的调用,也就导致了该问题。
if (mounted) {
setState(() {
this._books = dataModel.books
});
}
5. Waiting for another flutter command to release the startup lock…等待另一个flutter命令释放启动锁
- 退出 VS Code。
- 打开 flutter 安装目录 如:...\flutter\bin\cache 删除里面的 lockfile。
- 重新打开 VS Code。
原因:当你的项目异常关闭,下次启动就会出现上面的一行话, 此时需要打开 flutter/bin/cache/lockfile,删除就行了, 或者直接用下面的命令:rm ./flutter/bin/cache/lockfile。
6. 在 Stateless 控件内部或者浮层内部刷新,可以使用 StatefullBuilder
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 的是否选中的状态
7. 平台相关的判断
只关心是否是 iOS 和 Android 的情况下不需要依赖 context
,优先使用 Platform
Platform.isAndroid
Platform.isIOS
需要详细知道具体哪个平台才使用 TargetPlatform
这个API的缺点是需要依赖 context
这个参数
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.android) {
...
} else if (platform == TargetPlatform.iOS) {
...
}
8. ScrollView 滑动隐藏键盘
stackoverflow.com/questions/5…
使用ScrollView的keyboardDismissBehavior
属性
ListView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag
)
9. 回调写法
a.无参数回调
VoidCallback
b.有一个参数回调
ValueChanged
c.参数大于一个
可以通过typedef
自定义一个函数
下面是Example用法
final VoidCallback onPressed;
final ValueChanged<T> onSelectHandler;
typedef ImageSwiperOnTap = void Function(int index, List<String> imgUrls);
10. flutter pub get is stuck
可以通过切换flutter镜像到中文站点来解决
使用系统shell,请编辑
使用oh_my_zsh, 需要编辑.zshrc
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
保存文件后,关闭,下次重新打开终端生效
再执行flutter pub get
查看速度是否正常
11. 如何计算Text的行数,或者是否超过几行
stackoverflow.com/questions/5…
计算是否超过几行
return LayoutBuilder(builder: (context, size) {
final span = TextSpan(text: yourText, style: yourStyle);
final tp = TextPainter(text: span, maxLines: 3);
tp.layout(maxWidth: size.maxWidth);
if (tp.didExceedMaxLines) {
// The text has more than three lines.
// TODO: display the prompt message
return Container(color: Colors.red);
} else {
return Text(yourText, style: yourStyle);
}
});
计算行数
List<ui.LineMetrics> lines = textPainter.computeLineMetrics();
int numberOfLines = lines.length;
12. 元素查找 (firstWhere)
stackoverflow.com/questions/5…
final Cards selectedCard = cards.length > 0
? cards.firstWhere((element) => element.id == selectedTag.id,
orElse: () => null)
: null;
13. Gesturer 事件处理
优化点击事件的范围
使child组件的周围空白区域也有效
不设置的话,只会响应在child范围内的点击事件
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
// do something
},
child: Container()
)