dart 函数onTap在我的自定义微件中不起作用

btxsgosb  于 2023-03-21  发布在  其他
关注(0)|答案(1)|浏览(124)

我不知道为什么我的函数不起作用。甚至print语句也不起作用(print语句被插入到下面“page”代码中的第一个按钮中)。当我的AnswerButton小部件不在另一个文件中,并且不是一个独立的小部件时,它曾经起作用。
我的主要问题是--为什么连print语句都不起作用?

页码

import 'package:flutter/material.dart';
import 'package:quotes/database/database_helper.dart';
import 'package:quotes/models/quote.dart';
import 'package:quotes/random/random_generator.dart';
import 'package:quotes/requests/network_helper.dart';
import '../answer_buttons.dart';
import '../const.dart';
import 'package:quotes/random/random_generator.dart';
import 'package:quotes/models/character.dart';

class QuizPage extends StatefulWidget {
  QuizPage({super.key});
  Quote? randomQuote;
  List<Character> randomCharacter = [];

  RandomGenerator randomQuoteGenerator = RandomGenerator();
  RandomGenerator randomCharacterGenerator = RandomGenerator();

  @override
  State<QuizPage> createState() => _QuizPageState();
}

class _QuizPageState extends State<QuizPage> {
  String? firstname;
  String? lastname;
  int? randomNumber;

  @override
  void initState() {
    () async {
      widget.randomQuote = await getNewQuote();
      setState(() {});
      super.initState();
    };
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Center(
          child: Text(
            'Guess the Office quote!',
          ),
        ),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Expanded(
            flex: 2,
            child: Container(
              height: double.infinity,
              width: double.infinity,
              margin: EdgeInsets.only(
                  top: 80.0, left: 30.0, right: 30.0, bottom: 10.0),
              color: Colors.red,
              child: Center(
                  child: Text(widget.randomQuote?.quote ??
                      'Press a button to continue!')),
            ),
          ),
          Expanded(
            flex: 3,
            child: Padding(
              padding: const EdgeInsets.only(
                top: 100,
              ),
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 30.0, vertical: 0),
                child: Column(
                  children: [
                    AnswerButtons(
                      functionOnTap: () async {
                        print('function');
                        Quote newQuote = await getNewQuote();
                        setState(() {
                          widget.randomQuote = newQuote;
                        });
                      },
                      buttonText: '1231',
                    ),
                    AnswerButtons(
                      functionOnTap: () async {
                        Quote newQuote = await getNewQuote();
                        setState(() {
                          widget.randomQuote = newQuote;
                        });
                      },
                      buttonText: '1231',
                    ),
                    AnswerButtons(
                      functionOnTap: () async {
                        Quote newQuote = await getNewQuote();
                        setState(() {
                          widget.randomQuote = newQuote;
                        });
                      },
                      buttonText: '1231',
                    ),
                    AnswerButtons(
                      functionOnTap: () async {
                        Quote newQuote = await getNewQuote();
                        setState(() {
                          widget.randomQuote = newQuote;
                        });
                      },
                      buttonText: '1231',
                    ),
                  ],
                ),
              ),
            ),
          )
        ],
      ),
    );
  }

  Future<Quote> getNewQuote() async {
    return widget.randomQuoteGenerator.getRandomObjectFromListWithoutDuplicates(
        await DatabaseHelper.instance.getQuotes());
  }

  Future getNewCharacters() async {
    return widget.randomCharacterGenerator
        .getAListOfRandomNumbersWithoutDuplicates(
            await DatabaseHelper.instance.getCharacters(), 4);
  }
}

自定义小窗口

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'const.dart';

class AnswerButtons extends StatefulWidget {
  const AnswerButtons(
      {Key? key, required this.functionOnTap, required this.buttonText})
      : super(key: key);
  final String buttonText;
  final Function functionOnTap;
  @override
  _AnswerButtonsState createState() => _AnswerButtonsState();
}

class _AnswerButtonsState extends State<AnswerButtons> {
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: MediaQuery.of(context).size.width * buttonWidthMultiplier,
      height: MediaQuery.of(context).size.height * buttonHeightMultiplier,
      child: InkWell(
        onTap: () {
          widget.functionOnTap;
        },
        child: Center(
          child: Text(widget.buttonText),
        ),
      ),
    );
  }
}

我尝试使用setState并将Future<Quote> getNewQuote()重构为一个void函数来更新widget.randomQuote,但这些都不起作用。

tkclm6bt

tkclm6bt1#

问题出在AnswerButtons代码中:

class _AnswerButtonsState extends State<AnswerButtons> {
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: MediaQuery.of(context).size.width * buttonWidthMultiplier,
      height: MediaQuery.of(context).size.height * buttonHeightMultiplier,
      child: InkWell(
        onTap: () {
          // *** This is the problem ***
          widget.functionOnTap;
        },
        child: Center(
          child: Text(widget.buttonText),
        ),
      ),
    );
  }
}

为了真正调用widget.functionOnTap,需要将其 * 直接 * 传递给onTap属性,或者添加括号以便在闭包中调用它。
所以要么像这样:

onTap: widget.functionOnTap,

或者这个:

onTap: () {
  widget.functionOnTap();
  //  Add parentheses ^^
},
  • 编辑 *:

你的原始代码不起作用的原因是你传递了一个函数给onTap,但是这个函数实际上并没有做任何事情--它只是包含了一个对widget.functionOnTap的引用,但是没有调用它,因为括号不见了。
这就好比你有一个这样的函数:

final x = "foo";

void Function bar() {
  x;
}

在这段代码中,bar()引用x,但不对它做任何事情,因此该函数是一个noop。

相关问题