TextField回车换行控制
// 键盘确认键样式
textInputAction: TextInputAction.search,
// 实现该方法,阻止onSubmitted 键盘回落
onEditingComplete: () {
// 自定义回车换行, flutter没有找到换行方式
String _temp = _controller.text + '\n';
_controller.text = _temp;
/// 控制光标在最后一个字符
_controller.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: _temp.length));
},
onSubmitted: (v) {
print(_controller.text);
},
获取 上文中 provider 方式
// 取context(必须在创建ChangeNotifierProvider 的context后面才能获取搭到)上的provider对象
cartModel = ChangeNotifierProvider.of<CartModel>(context, listen: false).方法();
userViewModel = context.read<UserViewModel>();
定义局部ChangeNotifierProvider
ChangeNotifierProvider(
create: (_) => CallNumberViewModel(),
child: CallNumberKeyBoardWidget(
),
);
tips: ViewModel 如果不关联UI,仅 viewModel.addListener(), 监听状态,页面dispose 不会触发ViewModel 的dispose,也就是说需要手动才能释放。
@override
void dispose() {
viewModel.dispose();
super.dispose();
}
系统控件(CupertinoSwitch)无法改变大小,可以变更scale
Transform.scale(
scale: 0.8,
child: CupertinoSwitch(
value: true,
onChanged: (v) {},
activeColor: AIColor.primary,
trackColor: AIColor.buttonBorder,
),
)
Completer 同步转异步
Future<bool> checkBindedBoxStatus() async {
ServerBoxBindType bindType = await _checkBindBox();
if (bindType == ServerBoxBindType.bindOther) {
/// 异步状态器
Completer<bool> completer = new Completer();
AIRaisedDialog.showDialog(
'当前会议室已关联其他Pad的小智云汇控,是否替换?',
ontapConfirm: () {
completer.complete(true);
},
ontapCancel: () {
completer.complete(false);
},
);
/// completer.future不会立即执行, 会等待 completer.complete 结束后才回调
return completer.future;
} else if (bindType == ServerBoxBindType.error) {
return false;
} else {
return true;
}
}
Completer 设置超时时间。可以用于不同逻辑(websocket 信令发送,结响应)绑定在一起实现类似Http请求,request =》response 方式回调
// 定义变量
Completer? _task;
// 创建 Completer
// 设置超时时间
_task = Completer();
_task!.future.timeout(Duration(seconds: 60), onTimeout: () {
// 超时 回调
},
);
// ======================
// 响应 成功后,结束Completer,完成任务,
_task?.complete(null);
_task = null;
ListView相关scrollview滚动问题
如果没有可滚动区域,使用不当会报错
assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.');
原因
1、调用了animateToPage
2、获取了 .offset
解决方案:
if(_pageController.hasClients) {
/// 做相关处理
}
Future<void> animateTo(
double offset, {
@required Duration duration,
@required Curve curve,
}) {
assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.');
final List<Future<void>> animations = List<Future<void>>(_positions.length);
for (int i = 0; i < _positions.length; i += 1)
animations[i] = _positions[i].animateTo(offset, duration: duration, curve: curve);
return Future.wait<void>(animations).then<void>((List<void> _) => null);
}
Dart 2.12 版本开始支持空安全
- 空安全之前;所有对象都可以为null, 即所有对象都继承Null对象
- 空安全之后; 所有对象基类为Object,Null 分离独立出来。Null 与 Object 分开