类型'()=> Null'不是类型'(TapDownDetails)=> void'的子类型

时间:2020-08-10 09:07:00

标签: flutter dart

我正在练习BMI应用程序。我已经完成了所有工作,目前正在提取代码。我创建了一个名为ReusableAgeWeightCard的类,并在该处插入了onTapDownMinus,onTapUp,onTapCancel,onPressMinus,onTapDownPlus,onPressPlus函数。我不知道我对TapDownDetails详细信息犯了什么错误?

class ReusableAgeWeightCard extends StatelessWidget {
  final Widget changeMode;
  final String label;
  final String unit;
  final int si;
  final Function onTapDownMinus;
  final Function onTapUp;
  final Function onTapCancel;
  final Function onPressMinus;
  final Function onTapDownPlus;
  final Function onPressPlus;
  ReusableAgeWeightCard({
    @required this.label,
    this.changeMode,
    this.unit,
    @required this.si,
    @required this.onTapDownMinus,
    @required this.onTapUp,
    @required this.onTapCancel,
    @required this.onPressMinus,
    @required this.onTapDownPlus,
    @required this.onPressPlus,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(6.0),
      margin: EdgeInsets.all(15.0),
      decoration: BoxDecoration(
        color: kActiveCardColor,
        borderRadius: BorderRadius.circular(15.0),
      ),
      child: Stack(
        alignment: Alignment.topRight,
        children: <Widget>[
          changeMode,
          Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Text(
                label,
                style: kLabelTextStyle,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.baseline,
                textBaseline: TextBaseline.alphabetic,
                children: <Widget>[
                  Text(
                    si.toString(),
                    style: kNumberMediumTextStyle,
                  ),
                  Text(
                    unit,
                    style: kLabelTextStyle,
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  GestureDetector(
                    onTapDown: onTapDownMinus,
                    onTapUp: onTapUp,
                    onTapCancel: onTapCancel,
                    onTap: onPressMinus,
                    child: RawMaterialButton(
                      elevation: 6.0,
                      fillColor: Color(0xff4c4f5e),
                      shape: CircleBorder(),
                      constraints: BoxConstraints.tightFor(
                        height: 56.0,
                        width: 56.0,
                      ),
                      child: Icon(
                        FontAwesomeIcons.minus,
                        size: 25.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 10.0,
                  ),
                  GestureDetector(
                    onTapDown: onTapDownPlus,
                    onTapUp: onTapUp,
                    onTapCancel: onTapCancel,
                    onTap: onPressPlus,
                    child: RawMaterialButton(
                      elevation: 6.0,
                      fillColor: Color(0xff4c4f5e),
                      shape: CircleBorder(),
                      constraints: BoxConstraints.tightFor(
                        height: 56.0,
                        width: 56.0,
                      ),
                      child: Icon(
                        FontAwesomeIcons.plus,
                        size: 25.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              )
            ],
          ),
        ],
      ),
    );
  }
}
ReusableAgeWeightCard(
                      label: 'AGE',
                      unit: '',
                      si: age,
                      onTapDownMinus: (TapDownDetails details) {
                        minusOnTapDown('age');
                      },
                      onTapUp: (TapUpDetails details) {
                        cancelTimer();
                      },
                      onTapCancel: () {
                        cancelTimer();
                      },
                      onPressMinus: () {
                        minusOnPress('age');
                      },
                      onTapDownPlus: () {
                        plusOnTapDown('age');
                      },
                      onPressPlus: () {
                        plusOnPress('age');
                      }),

这是功能

void minusOnTapDown(String parameter) {
    if (parameter == 'age') {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          age--;
          if (age <= 1) {
            timer.cancel();
            age = 1;
          }
        });
      });
    } else if (parameter == 'pound') {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          pound--;
          if (pound <= 1) {
            timer.cancel();
            pound = 1;
          }
        });
      });
    } else {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          kg--;
          if (kg <= 1) {
            timer.cancel();
            kg = 1;
          }
        });
      });
    }
  }

  void plusOnTapDown(String parameter) {
    if (parameter == 'age') {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          age++;
          if (age > 117) {
            timer.cancel();
            age = 117;
          }
        });
      });
    } else if (parameter == 'pound') {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          pound++;
          if (pound >= 450) {
            timer.cancel();
          }
        });
      });
    } else {
      timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
        setState(() {
          kg++;
          if (kg >= 204) {
            timer.cancel();
            kg = 204;
          }
        });
      });
    }
  }

  void cancelTimer() {
    setState(() {
      timer.cancel();
    });
  }

  void minusOnPress(String parameter) {
    if (parameter == 'age') {
      setState(() {
        age--;
        if (age <= 1) {
          age = 1;
        }
      });
    } else if (parameter == 'pound') {
      setState(() {
        pound--;
        if (pound <= 1) {
          pound = 1;
        }
      });
    } else {
      setState(() {
        kg--;
        if (kg <= 1) {
          kg = 1;
        }
      });
    }
  }

  void plusOnPress(String parameter) {
    if (parameter == 'age') {
      setState(() {
        age++;
        if (age >= 117) {
          age = 117;
        }
      });
    } else if (parameter == 'pound') {
      setState(() {
        pound++;
        if (pound >= 450) {
          pound = 450;
        }
      });
    } else {
      setState(() {
        kg++;
        if (kg >= 204) {
          kg = 204;
        }
      });
    }
  }

这是错误

Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 3,474ms.
I/flutter ( 2903): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 2903): The following _TypeError was thrown building ReusableAgeWeightCard(dirty):
I/flutter ( 2903): type '() => Null' is not a subtype of type '(TapDownDetails) => void'
I/flutter ( 2903): 
I/flutter ( 2903): The relevant error-causing widget was:
I/flutter ( 2903):   ReusableAgeWeightCard file:///D:/Other/App/Flutter/bmi/lib/screen/input_page.dart:420:26
I/flutter ( 2903): 
I/flutter ( 2903): When the exception was thrown, this was the stack:
I/flutter ( 2903): #0      ReusableAgeWeightCard.build (package:bmi/components/reusable_age_weight_card.dart:92:32)
I/flutter ( 2903): #1      StatelessElement.build (package:flutter/src/widgets/framework.dart:4576:28)
I/flutter ( 2903): #2      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
I/flutter ( 2903): #3      Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
I/flutter ( 2903): #4      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5)
I/flutter ( 2903): #5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5)
I/flutter ( 2903): ...     Normal element mounting (7 frames)
I/flutter ( 2903): #12     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 2903): #13     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
I/flutter ( 2903): ...     Normal element mounting (7 frames)
I/flutter ( 2903): #20     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 2903): #21     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
I/flutter ( 2903): ...     Normal element mounting (19 frames)
I/flutter ( 2903): #40     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 2903): #41     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
I/flutter ( 2903): ...     Normal element mounting (193 frames)
I/flutter ( 2903): #234    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 2903): #235    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5947:32)
I/flutter ( 2903): ...     Normal element mounting (238 frames)
I/flutter ( 2903): #473    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14)
I/flutter ( 2903): #474    Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18)
I/flutter ( 2903): #475    RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1148:16)
I/flutter ( 2903): #476    RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1119:5)
I/flutter ( 2903): #477    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1061:17)
I/flutter ( 2903): #478    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2607:19)
I/flutter ( 2903): #479    RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1060:13)
I/flutter ( 2903): #480    WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:941:7)
I/flutter ( 2903): #481    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:922:7)
I/flutter ( 2903): (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
I/flutter ( 2903): 
I/flutter ( 2903): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter ( 2903): Another exception was thrown: type '() => Null' is not a subtype of type '(TapDownDetails) => void'

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following _TypeError was thrown building ReusableAgeWeightCard(dirty):
type '() => Null' is not a subtype of type '(TapDownDetails) => void'

The relevant error-causing widget was: 
  ReusableAgeWeightCard file:///D:/Other/App/Flutter/bmi/lib/screen/input_page.dart:420:26
When the exception was thrown, this was the stack: 
#0      ReusableAgeWeightCard.build (package:bmi/components/reusable_age_weight_card.dart:92:32)
#1      StatelessElement.build (package:flutter/src/widgets/framework.dart:4576:28)
#2      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
#3      Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
#4      StatelessElement.update (package:flutter/src/widgets/framework.dart:4583:5)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
type '() => Null' is not a subtype of type '(TapDownDetails) => void'
The relevant error-causing widget was: 
  ReusableAgeWeightCard file:///D:/Other/App/Flutter/bmi/lib/screen/input_page.dart:487:32
════════════════════════════════════════════════════════════════════════════════════════════════════

1 个答案:

答案 0 :(得分:0)

您要传递给GestureDetector的onTapDown参数的函数应为“ Function(TapDownDetails details)”类型。目前,您正在将VoidCallback传递给它。
我只留下了需要纠正的部分。

class ReusableAgeWeightCard extends StatelessWidget {

  final GestureTapDownCallback onTapDownMinus;
  final GestureTapDownCallback onTapDownPlus;

 }

当您使用新的小部件时-不要忘记将正确的函数传递给这些参数。
在上面的示例中,“ onTapDownPlus”定义不正确。

ReusableAgeWeightCard(
   onTapDownMinus: (details) {}, // This one is correct in your code
   onTapDownPlus: (details) {}, // This one has to be fixed
)

如果您不打算在功能代码中使用“详细信息”,则始终可以按以下示例中的说明定义功能(使用“空”参数)。

ReusableAgeWeightCard(
   onTapDownMinus: (_) {},
   onTapDownPlus: (_) {},
)

UPD:添加了完整的窗口小部件代码,并修复了“索引为0的堆栈窗口小部件”。

class ReusableAgeWeightCard extends StatelessWidget {
  final Widget changeMode;
  final String label;
  final String unit;
  final int si;
  final GestureTapDownCallback onTapDownMinus;
  final Function onTapUp;
  final Function onTapCancel;
  final Function onPressMinus;
  final GestureTapDownCallback onTapDownPlus;
  final Function onPressPlus;
  ReusableAgeWeightCard({
    @required this.label,
    this.changeMode,
    this.unit,
    @required this.si,
    @required this.onTapDownMinus,
    @required this.onTapUp,
    @required this.onTapCancel,
    @required this.onPressMinus,
    @required this.onTapDownPlus,
    @required this.onPressPlus,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(6.0),
      margin: EdgeInsets.all(15.0),
      decoration: BoxDecoration(
        color: kActiveCardColor,
        borderRadius: BorderRadius.circular(15.0),
      ),
      child: Stack(
        alignment: Alignment.topRight,
        children: <Widget>[
          if( changeMode != null) changeMode, // <-- Fixed this line with a conditional rendering
          Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Text(
                label,
                style: kLabelTextStyle,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.baseline,
                textBaseline: TextBaseline.alphabetic,
                children: <Widget>[
                  Text(
                    si.toString(),
                    style: kNumberMediumTextStyle,
                  ),
                  Text(
                    unit,
                    style: kLabelTextStyle,
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  GestureDetector(
                    onTapDown: onTapDownMinus,
                    onTapUp: onTapUp,
                    onTapCancel: onTapCancel,
                    onTap: onPressMinus,
                    child: RawMaterialButton(
                      elevation: 6.0,
                      fillColor: Color(0xff4c4f5e),
                      shape: CircleBorder(),
                      constraints: BoxConstraints.tightFor(
                        height: 56.0,
                        width: 56.0,
                      ),
                      child: Icon(
                        FontAwesomeIcons.minus,
                        size: 25.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 10.0,
                  ),
                  GestureDetector(
                    onTapDown: onTapDownPlus,
                    onTapUp: onTapUp,
                    onTapCancel: onTapCancel,
                    onTap: onPressPlus,
                    child: RawMaterialButton(
                      elevation: 6.0,
                      fillColor: Color(0xff4c4f5e),
                      shape: CircleBorder(),
                      constraints: BoxConstraints.tightFor(
                        height: 56.0,
                        width: 56.0,
                      ),
                      child: Icon(
                        FontAwesomeIcons.plus,
                        size: 25.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              )
            ],
          ),
        ],
      ),
    );
  }
}