参数类型 '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);
}); }
我是 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);
}); }