如何在 Flutter 中正确设置 onPressed?

Posted

技术标签:

【中文标题】如何在 Flutter 中正确设置 onPressed?【英文标题】:How to set onPressed properly in Flutter? 【发布时间】:2019-08-23 03:39:43 【问题描述】:

我在 Flutter 中为一个 floatingActionButton 设置“onPressed”,它给了我一个奇怪的错误,尽管我在教程中看到几乎相同的代码......

注意:此按钮位于脚手架小部件中...

注意:“context”是包含脚手架小部件的函数中的参数

注意:我尝试使用凸起的按钮并给出了相同的错误

ma​​in.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,
        )
      )
    );
  

ma​​nage.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 在控制台中响应但在显示中没有响应

将数据从另一个类传递到另一个类 onPressed Flutter

Flutter - 容器 onPressed?