如何在 Flutter 中正确设置 onPressed?
Posted
技术标签:
【中文标题】如何在 Flutter 中正确设置 onPressed?【英文标题】:How to set onPressed properly in Flutter? 【发布时间】:2019-08-23 03:39:43 【问题描述】:我在 Flutter 中为一个 floatingActionButton 设置“onPressed”,它给了我一个奇怪的错误,尽管我在教程中看到几乎相同的代码......
注意:此按钮位于脚手架小部件中...
注意:“context”是包含脚手架小部件的函数中的参数
注意:我尝试使用凸起的按钮并给出了相同的错误
main.dart:
import 'package:flutter/material.dart';
import './pages/home.dart';
main(List<String> args) => runApp(HomePage());
home.dart:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:english_words/english_words.dart';
import './item.dart';
import 'dart:math';
import './tabs/create.dart';
import './tabs/manage.dart';
class HomePage extends StatefulWidget
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<HomePage>
Color _mainColor = Colors.green;
final List<Map<String, String>> mainList = [];
List<IconData> iconsList = [
Icons.add,
Icons.add_alarm,
Icons.adjust,
Icons.all_inclusive,
Icons.android,
Icons.attach_money,
Icons.audiotrack,
Icons.battery_charging_full
];
showTheDialog(BuildContext context)
showDialog(
context: context,
builder: (BuildContext context)
return AlertDialog(
title: Text("Welcome to max!"),
content: Text("We hope you enjoy our app :)"),
actions: <Widget>[
FlatButton(
child: Text("Ok"),
onPressed: () => setState(()
_mainColor = Colors.lightGreen;
),
),
FlatButton(
child: Text("Ok"),
onPressed: () => setState(()
_mainColor = Colors.lightGreen;
),
),
],
);
);
Icon getRandomIcon()
Random randInt = Random();
int randNum = randInt.nextInt(8);
return Icon(
iconsList[randNum],
size: 35,
color: _mainColor,
);
Widget _buildListItem(BuildContext context, int index)
return Card(
child: InkWell(
onTap: () => Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => Item())),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
WordPair.random().asCamelCase,
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold, color: _mainColor),
),
],
),
));
Widget checkItems()
if (mainList.isEmpty)
return Center(
child: Text(
"There are no Items here",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
);
else
return ListView.builder(
itemBuilder: _buildListItem,
itemCount: mainList.length,
);
@override
Widget build(BuildContext context)
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: _mainColor));
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Max Course",
theme: ThemeData(
primarySwatch: _mainColor,
),
home: DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: <Widget>[
Tab(
text: "Create Item",
icon: Icon(Icons.create),
),
Tab(
text: "Manage Item",
icon: Icon(Icons.list),
),
Tab(
text: "Create Item",
icon: Icon(Icons.create),
),
Tab(
text: "Manage Item",
icon: Icon(Icons.list),
)
],
),
centerTitle: true,
backgroundColor: _mainColor,
title: Text(
"Max",
textDirection: TextDirection.ltr,
style: TextStyle(
fontFamily: "Arciform",
fontWeight: FontWeight.w300,
fontSize: 25,
),
),
),
body: TabBarView(
children: <Widget>[
CreateItems(),
ManageItems(),
CreateItems(),
ManageItems(),
],
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => showTheDialog(context),
),
drawer: Drawer(
child: Center(
child: FlatButton(
child: Text("test"),
onPressed: () => showTheDialog(context),
),
),
),
),
));
create.dart:
import 'package:flutter/material.dart';
class CreateItems extends StatelessWidget
@override
Widget build(BuildContext context)
return Center(
child: Text(
"Create Items..",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
)
)
);
manage.dart:
import 'package:flutter/material.dart';
class ManageItems extends StatelessWidget
@override
Widget build(BuildContext context)
return Center(
child: Text(
"Manage Items..",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
)
)
);
错误是:
I/flutter (11665): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ I/flutter (11665): The following assertion was thrown while handling a gesture: I/flutter (11665): No MaterialLocalizations found. I/flutter (11665): HomePage widgets require MaterialLocalizations to be provided by a Localizations widget ancestor. I/flutter (11665): Localizations are used to generate many different messages, labels,and abbreviations which are used I/flutter (11665): by the material library. I/flutter (11665): To introduce a MaterialLocalizations, either use a MaterialApp at the root of your application to I/flutter (11665): include them automatically, or add a Localization widget with a MaterialLocalizations delegate. I/flutter (11665): The specific widget that could not find a MaterialLocalizations ancestor was: I/flutter (11665): HomePage I/flutter (11665): The ancestors of this widget were: I/flutter (11665): [root] I/flutter (11665): When the exception was thrown, this was the stack: I/flutter (11665): #0 debugCheckHasMaterialLocalizations.<anonymous closure> (package:flutter/src/material/debug.dart:124:7) I/flutter (11665): #1 debugCheckHasMaterialLocalizations (package:flutter/src/material/debug.dart:127:4) I/flutter (11665): #2 showDialog (package:flutter/src/material/dialog.dart:701:10) I/flutter (11665): #3 _HomePageState.showTheDialog (package:max/pages/home.dart:29:5) I/flutter (11665): #4
_HomePageState.build.<anonymous closure> (package:max/pages/home.dart:154:30) I/flutter (11665): #5
_InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:513:14) I/flutter (11665):
#6 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:568:30) I/flutter (11665):
#7 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:166:24) I/flutter (11665): #8 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:246:9) I/flutter (11665): #9 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:175:7) I/flutter (11665): #10 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:436:9) I/flutter (11665): #11 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12) I/flutter (11665): #12 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11) I/flutter (11665): #13
_WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:214:19) I/flutter (11665):
#14 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:192:22) I/flutter (11665):
#15 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:149:7) I/flutter (11665):
#16 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:101:7) I/flutter (11665):
#17 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:85:7) I/flutter (11665):
#21 _invoke1 (dart:ui/hooks.dart:223:10) I/flutter (11665): #22 _dispatchPointerDataPacket (dart:ui/hooks.dart:144:5) I/flutter (11665): (elided 3 frames from package dart:async) I/flutter (11665): Handler: onTap I/flutter (11665): Recognizer: I/flutter (11665): TapGestureRecognizer#b0516(debugOwner: GestureDetector, state: possible, won arena, finalPosition: I/flutter (11665): Offset(299.0,
544.2), sent tap down) I/flutter (11665): ════════════════════════════════════════════════════════════════════════════════════════════════════ I/flutter (11665): Another exception was thrown: No MaterialLocalizations found.
【问题讨论】:
你能添加更多代码吗? 阅读堆栈,我怀疑错误出在您提出的代码中,因为它与本地化有关。见日志use a MaterialApp at the root of your application to
@diegoveloper 我已经编辑了帖子
@TruongSinh 帖子已编辑
@diegoveloper,非常感谢:)
【参考方案1】:
尝试使用Builder
小部件获取正确的BuildContext
home: DefaultTabController(
length: 4,
child: Builder(
builder: (newContext)
return Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: <Widget>[
Tab(
text: "Create Item",
icon: Icon(Icons.create),
),
Tab(
text: "Manage Item",
icon: Icon(Icons.list),
),
Tab(
text: "Create Item",
icon: Icon(Icons.create),
),
Tab(
text: "Manage Item",
icon: Icon(Icons.list),
)
],
),
centerTitle: true,
backgroundColor: _mainColor,
title: Text(
"Max",
style: TextStyle(
fontFamily: "Arciform",
fontWeight: FontWeight.w300,
fontSize: 25,
),
),
),
body: TabBarView(
children: <Widget>[
CreateItems(),
ManageItems(),
CreateItems(),
ManageItems(),],
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => showTheDialog(newContext),
),
drawer: Drawer(
child: Center(
child: FlatButton(
child: Text("test"),
onPressed: () => showTheDialog(newContext),
),
),
),
);
,
),
),
【讨论】:
以上是关于如何在 Flutter 中正确设置 onPressed?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 onPressed 值发送到另一个小部件 Flutter
OnPressed 将 activeColor 设置为列表的按钮,并将 inactiveColor 设置为其他 btns - Flutter
如何左对齐 Flutter 中的 OutlineButton 图标
Flutter:IconButton onPressed 在控制台中响应但在显示中没有响应