参数类型 'AnimationController?' 无法分配给参数类型 'Animation<double>'

The argument type 'AnimationController?' can't be assigned to the parameter type 'Animation<double>'

我是 Flutter 新手。

所以我尝试在 flutter 中使用曲线动画,但它给了我一个类型错误,如标题中所述。我在下面分享了我的 main.dart 和 welcome_screen.dart。在 documentation https://flutter.dev/docs/development/ui/animations/tutorial 中,他们还使用了 Animationcontroller 和一条曲线(连同 Tween),我想我也做了同样的事情。如何解决?

main.dart

import 'package:flutter/material.dart'; import 'package:flash_chat/screens/welcome_screen.dart'; import 'package:flash_chat/screens/login_screen.dart'; import 'package:flash_chat/screens/registration_screen.dart'; import 'package:flash_chat/screens/chat_screen.dart';

void main() => runApp(FlashChat());

class FlashChat extends StatelessWidget {   @override   Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        textTheme: TextTheme(bodyText1: TextStyle(color: Colors.black54)),
      ),
      initialRoute: WelcomeScreen.id,
      routes: {
        WelcomeScreen.id: (context) => WelcomeScreen(),
        LoginScreen.id: (context) => LoginScreen(),
        RegistrationScreen.id: (context) => RegistrationScreen(),
        ChatScreen.id: (context) => ChatScreen(),
      },
    );   } }

welcome_screen.dart

import 'package:flutter/material.dart'; import 'package:flash_chat/screens/login_screen.dart'; import 'package:flash_chat/screens/registration_screen.dart';

class WelcomeScreen extends StatefulWidget {   static const String id
= 'welcome_screen';

  @override   _WelcomeScreenState createState() =>
_WelcomeScreenState(); }

class _WelcomeScreenState extends State<WelcomeScreen>
    with SingleTickerProviderStateMixin {   AnimationController? controller;   Animation? animation;

  @override   void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1),
      upperBound: 100,
    );
    animation = CurvedAnimation(parent: controller, curve: Curves.decelerate);
    controller!.forward();

    controller!.addListener(() {
      setState(() {});
      print(controller!.value);
    });   }

  @override   Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 24),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              children: [
                Hero(
                  tag: 'logo',
                  child: Container(
                    child: Image.asset('images/logo.png'),
                    height: controller!.value,
                  ),
                ),
                Text(
                  'Flash Chat',
                  style: TextStyle(
                    fontSize: 45.0,
                    fontWeight: FontWeight.w900,
                    color: Colors.blueGrey.shade300,
                  ),
                ),
              ],
            ),
            SizedBox(
              height: 48,
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: Material(
                elevation: 5.0,
                color: Colors.lightBlueAccent,
                borderRadius: BorderRadius.circular(30.0),
                child: TextButton(
                  style: ButtonStyle(
                    foregroundColor:
                        MaterialStateProperty.all<Color>(Colors.white),
                  ),
                  onPressed: () {
                    Navigator.pushNamed(context, LoginScreen.id);
                  },
                  child: Text('Login'),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: Material(
                elevation: 5.0,
                color: Colors.lightBlueAccent,
                borderRadius: BorderRadius.circular(30.0),
                child: TextButton(
                  style: ButtonStyle(
                    foregroundColor:
                        MaterialStateProperty.all<Color>(Colors.white),
                  ),
                  onPressed: () {
                    Navigator.pushNamed(context, RegistrationScreen.id);
                  },
                  child: Text('Register'),
                ),
              ),
            )
          ],
        ),
      ),
    );   } }

我的完整错误如下

Performing hot reload...
Syncing files to device Lenovo TB 7504X...
lib/screens/welcome_screen.dart:25:41: Error: The argument type 'AnimationController?' can't be assigned to the parameter type 'Animation<double>' because 'AnimationController?' is nullable and 'Animation<double>' isn't.
 - 'AnimationController' is from 'package:flutter/src/animation/animation_controller.dart' ('/C:/src/flutter_windows_2.5.1-stable/flutter/packages/flutter/lib/src/animation/animation_controller.dart').
 - 'Animation' is from 'package:flutter/src/animation/animation.dart' ('/C:/src/flutter_windows_2.5.1-stable/flutter/packages/flutter/lib/src/animation/animation.dart').
    animation = CurvedAnimation(parent: controller, curve: Curves.decelerate);
                                        ^

您需要在此处使用 controller! CurvedAnimation(parent: controller!...,如下所示:

 @override   void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1),
      upperBound: 100,
    );
    animation = CurvedAnimation(parent: controller!, curve: Curves.decelerate);
    controller!.forward();

    controller!.addListener(() {
      setState(() {});
      print(controller!.value);
    });   }

AnimationController 可以分配给 Animation<Double>,因为 AnimationController extends Animation<double> 唯一的问题是 无效安全性 。在本教程中,他们使用 late 关键字初始化了 AnimationController,但由于您使用了 AnimationController?,因此您需要使其安全。

与 late 关键字一起使用的 AnimationController 在教程中他们已经初始化,因此使用 late 关键字你不需要在每个地方都设置 null 安全并且 initstate 它将初始化 compulasary 因为使用 late 关键字。

late AnimationController controller; 
  Animation? animation;

@override   void initState() {
  super.initState();
  controller = AnimationController(
    vsync: this,
    duration: Duration(seconds: 1),
    upperBound: 100,
  );
  animation = CurvedAnimation(parent: controller, curve: Curves.decelerate);
  controller.forward();

  controller.addListener(() {
    setState(() {});
    print(controller.value);
  });   }