1、退出App
SystemNavigator.pop()
2切诀、攔截返回鍵
WillPopScope(
child: Scaffold(),
onWillPop: () {
/// 如果回調(diào)返回一個解析為false的Future揩环,則攔截路由跳轉(zhuǎn)。
/// return Future.value(false);
return Future.value(true);
},
);
3幅虑、點擊空白取消TextField焦點 隱藏鍵盤
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
// 點擊空白取消所有輸入框焦點丰滑,隱藏鍵盤
FocusScope.of(context).requestFocus(FocusNode());
},
child:...,
)
behavior:表現(xiàn)方式。
默認[ HitTestBehavior.deferToChild]
enum HitTestBehavior {
/// 遵從其子女的目標 將在其范圍內(nèi)接收事件翘单,只有當他們的一個孩子被擊中時吨枉。
/// (child處理事件)
deferToChild,
/// 不透明的目標可以通過命中測試來命中,這使得它們既可以在其范圍內(nèi)接收事件哄芜,又可以防止其背后的目標也接收事件貌亭。
/// (自己處理事件)
opaque,
/// 半透明目標既可以在其范圍內(nèi)接收事件,也可以允許其背后的可視目標接收事件认臊。
/// (自己和chuild都可以處理事件)
translucent,
}
4圃庭、手動移除/獲取指定輸入框焦點
FocusNode _focusNode = FocusNode();
...
TextField(
focusNode: _focusNode,
...
)
// 移除焦點
_focusNode.unfocus();
// 獲得焦點
FocusScope.of(context).requestFocus(_focusNode);
// 是否獲得焦點的狀態(tài)
_focusNode.hasFocus
5、手動彈出/收起鍵盤
// 手動彈出鍵盤
SystemChannels.textInput.invokeMethod('TextInput.show');
// 手動收起鍵盤
SystemChannels.textInput.invokeMethod('TextInput.hide');
6失晴、自定義Widget實現(xiàn)PreferredSize
class CustomPreferredSize extends StatelessWidge implements PreferredSizeWidget {
CustomPreferredSize({
this.height = kToolbarHeight,
this.child,
});
final double height;
final Widget child;
@override
Widget build(BuildContext context) => child;
@override
Size get preferredSize => Size.fromHeight(height);
}
// 使用示例
//Scaffold(
// appBar: CustomPreferredSize(child: _AppBar()),
//);
//class _AppBar extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return AppBar(title: Text('DEMO'));
// }
//}
7剧腻、dart 千分位格式化金額(正則)
/// 千分位格式化金額
/// [toFixed] 保留多少位小數(shù)點 默認保留全部
/// formatMoney(123456) => 123,456
/// formatMoney(123456.1234) => 123,456.1234
/// formatMoney(123456.1234, toFixed: 2) => 123,456.12
static String formatMoney(Object val, {int toFixed}) {
if (toFixed != null) {
val = double.parse(val.toString()).toStringAsFixed(toFixed);
}
List<String> split = val.toString().split('.');
String str = split[0].replaceAll(RegExp(r"\B(?=(\d{3})+(?!\d))"), ",");
if (split.length > 1) return str + '.' + split[1];
return str;
}
8、監(jiān)測APP前后臺切換
class Demo extends StatefulWidget {
@override
_DemoState createState() => _DemoState ();
}
class _DemoState extends State<Demo> with SingleTickerProviderStateMixin, WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
print('切換至前臺');
}
super.didChangeAppLifecycleState(state);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
9涂屁、重啟APP
// 重啟APP組件
class ResetApp extends StatefulWidget {
ResetApp({@required this.child});
final Widget child;
static void reset(BuildContext context) async {
//查找頂層_ResetAppState并重啟
context.findAncestorStateOfType<_ResetAppState>().reset();
}
@override
_ResetAppState createState() => _ResetAppState();
}
class _ResetAppState extends State<ResetApp> {
Key _key = UniqueKey();
void reset() {
//重新生成key導致控件重新build 達到重啟APP的效果
setState(() => _key = UniqueKey());
}
@override
Widget build(BuildContext context) {
return KeyedSubtree(
key: _key,
child: widget.child,
);
}
}
保證ResetApp始終包裹住MaterialApp书在,如下
void main() {
runApp(
ResetApp(child: MaterialApp()),
);
}
需要重啟時調(diào)用 ↓
ResetApp.reset(context);
未完待續(xù)...