2024 最新 Flutter 教學 - Flutter 終極指南: 連結
從零開始學 Dart 程式設計: 連結
Flutter 程式設計入門實戰 30 天: 連結
哈囉~大家好,我是 KT ,今天【iT邦幫忙鐵人賽】挑戰第十八天,KT 將為大家來介紹,SnackBar 提示元件。
SnackBar 提示元件,會在螢幕下方,彈跳顯示訊息,幾秒後消失。
final snackBar = new SnackBar(content: new Text('顯示訊息'));
Scaffold.of(context).showSnackBar(snackBar);
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HKT線上教室'),
),
body: HomePage(),
));
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('顯示 SnackBar 訊息'),
onPressed: () {
//顯示 SnackBar 簡單基本訊息
final snackBar = new SnackBar(content: new Text('顯示訊息'));
Scaffold.of(context).showSnackBar(snackBar);
},
),
);
}
}
注意事項:
SnackBar 要顯示訊息是透過 Scaffold的showSnackBar 方法來顯示。所以要顯示訊息,務必要先拿到 Scaffold 的 context,否則會報錯無法顯示。當然可以直接在 body 後包一層 Builder 快速解決,不過 KT 建議不要寫出波動拳程式結構。所以在最一開始起手式章節 KT 就直接建議拆開,分成一小塊一小塊邏輯程式,維護、閱讀比較方便,降低程式耦合性比較容易擴充與變動。
/*
* 錯誤程式,執行會發生錯誤
*/
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HKT線上教室'),
),
body: Center(
child: RaisedButton(
child: Text('顯示 SnackBar 訊息'),
onPressed: () {
final snackBar = new SnackBar(content: new Text('顯示訊息'));
Scaffold.of(context).showSnackBar(snackBar);
},
),
),
));
}
}
會出現類似下方,錯誤 Log 訊息
flutter: ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
flutter: The following assertion was thrown while handling a gesture:
flutter: Scaffold.of() called with a context that does not contain a Scaffold.
flutter: No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This
flutter: usually happens when the context provided is from the same StatefulWidget as that whose build
flutter: function actually creates the Scaffold widget being sought.
flutter: There are several ways to avoid this problem. The simplest is to use a Builder to get a context that
flutter: is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
flutter: https://api.flutter.dev/flutter/material/Scaffold/of.html
flutter: A more efficient solution is to split your build function into several widgets. This introduces a
flutter: new context from which you can obtain the Scaffold. In this solution, you would have an outer widget
flutter: that creates the Scaffold populated by instances of your new inner widgets, and then in these inner
flutter: widgets you would use Scaffold.of().
flutter: A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the
flutter: key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
flutter: The context used was:
flutter: MyApp
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Scaffold.of (package:flutter/src/material/scaffold.dart:1188:5)
flutter: #1 MyApp.build.<anonymous closure> (package:demo_flutter/main.dart:20:22)
flutter: #2 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:635:14)
flutter: #3 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:711:32)
flutter: #4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
flutter: #5 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11)
flutter: #6 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:275:7)
flutter: #7 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:455:9)
flutter: #8 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13)
flutter: #9 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11)
flutter: #10 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
flutter: #11 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
flutter: #12 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
flutter: #13 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
flutter: #14 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
flutter: #18 _invoke1 (dart:ui/hooks.dart:250:10)
flutter: #19 _dispatchPointerDataPacket (dart:ui/hooks.dart:159:5)
flutter: (elided 3 frames from package dart:async)
flutter:
flutter: Handler: "onTap"
flutter: Recognizer:
flutter: TapGestureRecognizer#90ba4
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
void showMySnackBar(BuildContext context) {
final snackBar = new SnackBar(
content: new Text('顯示訊息'),
action: SnackBarAction(
label: '復原',
onPressed: () {
print('復原...');
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HKT線上教室'),
),
body: HomePage(),
));
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('顯示 SnackBar 訊息'),
onPressed: () {
showMySnackBar(context);
},
),
);
}
//顯示 SnackBar 訊息與自定義按鈕
void showMySnackBar(BuildContext context) {
final snackBar = new SnackBar(
content: new Text('顯示訊息'),
action: SnackBarAction(
label: '復原',
onPressed: () {
print('復原...');
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
}
那今天【iT邦幫忙鐵人賽】就介紹到這邊囉~
順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,加追蹤喔!也歡迎大家將這篇文章分享給更多人喔。
我們明天見囉!!!掰掰~
HKT 線上教室
http://tw-hkt.blogspot.com/
Background vector created by freepik
www.freepik.com
版本過時:現在需要使用 ScaffoldMessenger
:
final snackBar = SnackBar(content: Text('Hello'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);