我正在尝试点击Snackbar
来显示floatingActionbutton
。但是,当我单击floatingactionbutton
时,它什么也没有显示。这是我的代码。我正在使用StatefulWidget
。我调试并检查了onPressed函数是否也正在执行,但是以某种方式看不见Snackbar
。造成此问题的根本原因是什么?我觉得我传递的BuildContext有问题。
class MyApp extends StatefulWidget{
@override
MyAppState createState() {
// TODO: implement createState
return new MyAppState();
}
}
class MyAppState extends State<MyApp>{
File _image;
String _text;
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
_image = image;
final FirebaseVisionImage visionImage = FirebaseVisionImage.fromFile(_image);
final TextRecognizer textRecognizer = FirebaseVision.instance.textRecognizer();
final VisionText visionText = await textRecognizer.processImage(visionImage);
String detectedText = visionText.text;
setState(() {
_image = image;
_text = detectedText;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
title: new Text('Image Picker Example'),
),
body: new Center(
child: _image == null
? new Text('No image selected.')
: new Image.file(_image),
),
floatingActionButton: new FloatingActionButton(
onPressed: (){
showSnackBar(context);
// getImage();
},
tooltip: 'Pick Image',
child: new Icon(Icons.add_a_photo),
),
),
);
}
void showSnackBar(BuildContext context) {
final scaffold = Scaffold.of(context);
final snackBarContent = SnackBar(
content: Text("sagar"),
action: SnackBarAction(
label: 'UNDO', onPressed: scaffold.hideCurrentSnackBar),
);
scaffold.showSnackBar(snackBarContent);
}
}
答案 0 :(得分:2)
要显示 SnackBar 你可以这样使用:
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('User Logged In'),
));
以前的 SnackBar 是这样使用的:
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Rahul Kushwaha!'),
));
现在,SnackBar 由ScaffoldMessenger 管理。有关详细信息,请研究此 link
答案 1 :(得分:1)
class MyApp extends StatefulWidget{
@override
MyAppState createState() {
// TODO: implement createState
return new MyAppState();
}
}
class MyAppState extends State<MyApp>{
final GlobalKey<ScaffoldState> _scaffoldkey = new GlobalKey<ScaffoldState>();
File _image;
String _text;
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
_image = image;
final FirebaseVisionImage visionImage = FirebaseVisionImage.fromFile(_image);
final TextRecognizer textRecognizer = FirebaseVision.instance.textRecognizer();
final VisionText visionText = await textRecognizer.processImage(visionImage);
String detectedText = visionText.text;
setState(() {
_image = image;
_text = detectedText;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
key: _scaffoldkey,
appBar: new AppBar(
title: new Text('Image Picker Example'),
),
body: new Center(
child: _image == null
? new Text('No image selected.')
: new Image.file(_image),
),
floatingActionButton: new FloatingActionButton(
onPressed: (){
showSnackBar();
// getImage();
},
tooltip: 'Pick Image',
child: new Icon(Icons.add_a_photo),
),
),
);
}
void showSnackBar() {
final snackBarContent = SnackBar(
content: Text("sagar"),
action: SnackBarAction(
label: 'UNDO', onPressed: _scaffoldkey.currentState.hideCurrentSnackBar),
);
_scaffoldkey.currentState.showSnackBar(snackBarContent);
}
}
答案 2 :(得分:1)
之所以会这样,是因为所使用的BuildContext
没有Scaffold
的祖先,因此无法找到它来渲染SnackBar
,因为它取决于Scaffold
显示它。
根据of method文档:
当在相同的构建函数中实际创建了脚手架时, 构建函数的上下文参数不能用于查找 脚手架(因为它在返回的小部件“上方”)。在这样的 情况下,可以使用以下带有Builder的技术来提供 BuildContext位于“支架”下方的新作用域:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Demo') ), body: Builder( // Create an inner BuildContext so that the onPressed methods // can refer to the Scaffold with Scaffold.of(). builder: (BuildContext context) { return Center( child: RaisedButton( child: Text('SHOW A SNACKBAR'), onPressed: () { Scaffold.of(context).showSnackBar(SnackBar( content: Text('Hello!'), )); }, ), ); }, ), ); }
解决方案
将FloatingActionButton
包装在Builder
小部件中,将比使用GlobalKey
(@ Epizon答案已经提到)更加优雅。