本地存储
场景:flutter编译为H5时,从本地存储中读取数据
// WebViewController 中存储
final Map<String, dynamic> data = {
"name": "Some Name",
"id": "666",
};
final String jsonString = json.encode(data);
// 这里可以在取名上做区分:web.data
final script = "window.sessionStorage.setItem('web.data', JSON.stringify($jsonString));";
controller.runJavaScript(script);
// flutter中取出使用
final data = html.window.sessionStorage["web.data"];
if (data != null) {
final Map<String, dynamic> jsonData = json.decode(data);
final String name = jsonData["name"];
final String id = jsonData["id"];
}
按钮置于底部
Spacer 可以灵活配置你的Row/Column
官方文档中描述:Spacer创建一个可调整的空间隔,可用于调整Flex容器(如行或列)中窗口小部件之间的间距。
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: "按钮置于底部",
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
// some widget ...
const Spacer(),
CustomButton.normal(
text: "按钮",
onPressed: () => {
// do something...
}),
),
],
),
),
),
);
}
相关文档:
Dart API
Flutter Spacer
Flutter Spacer教程
输入框赋值
TextEditingController someController = TextEditingController();
TextFormField(
controller: securitiesIdController,
onChanged: (text) {
// 处理文本变化
someController.value = someController.value.copyWith(
text: text,
);
},
),
// 注意不要在onChanged回调中处理文本变化:
// 在onChanged回调中,确保只将文本内容设置回TextEditingController,
// 而不是直接将整个text参数赋值给TextEditingController。这可以避免循环更新的问题。
// 错误示范
TextFormField(
controller: securitiesIdController,
onChanged: (text) {
someController.text = text;
},
),
后台倒计时
Timer
有个属性:tick
。
既使callback
停止回调了,tick
也是一直在累加的。
利用这个tick
,只需要一行代码就可以解决此问题:
int _resCount = 60;
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
_resCount = 60 - timer.tick
})
});
点击按钮时隐藏键盘
给输入框添加focusNode
属性;
并在按钮点击事件中调用方法:FocusScope.of(context).unfocus();
FocusNode _focusNode = FocusNode();
TextField(
focusNode: _focusNode,
// 其他属性...
)
ElevatedButton(
onPressed: () {
FocusScope.of(context).unfocus();
// 处理按钮点击事件
},
child: Text('按钮'),
)
横向滚动-禁止弹性效果
ScrollController _scrollController = ScrollController();
CupertinoScrollbar(
controller: _scrollController,
child: SingleChildScrollView(
controller: _scrollController,
physics: const ClampingScrollPhysics(),
child: Column(
children: [
// Your content here
],
),
),
),
父组件调用子组件方法
/// 父组件
class FatherPage extends StatefulWidget {
const FatherPage({Key? key}) : super(key: key);
@override
State<FatherPage> createState() => _FatherPageState();
}
class _FatherPageState extends State<FatherPage> with SingleTickerProviderStateMixin {
// 使用 GlobalKey 来获取对’子组件’的引用
final GlobalKey<SonPageState> _SonPageStateKey = GlobalKey<SonPageState>();
// 父组件方法
void faSomeFun() {
// 调用子组件的方法
_SonPageStateKey.currentState?.someFun(),
);
@override
Widget build(BuildContext context) {
return Column(
children: [
SonPage(
// 给子组件添加key
key: _SonPageStateKey,
),
]
)
}
}
/// 子组件
class SonPageState extends StatefulWidget {
const SonPageState({Key? key}) : super(key: key);
@override
State<SonPageState> createState() => SonPageStateState();
}
class SonPageStateState extends State<SonPageState> {
// 需要被调用的方法
void someFun() {
// 做一些事
}
@override
Widget build(BuildContext context) {
return // some widget
}
}
报错集合
// 1
// pub finished with exit code 78
// flutter pub run build_runner build 时报错
// 解决:
flutter packages pub run build_runner build --delete-conflicting-outputs