Zeffry Reynando
Zeffry Reynando

Reputation: 3899

Flutter Animation<Color> : Class 'Color' has no instance method '-'

I make simple animation to change color Appbar using Tween[Color] , NotificationListener[ScrollNotification] and Appbar. I want change color Appbar and Action Icon while scrolling screen with this condition :

Logic

    if (notification.metrics.pixels == notification.metrics.minScrollExtent) {
      Future.delayed(Duration(seconds: 0), () => controllerAppbar.reverse());
    } else {
      Future.delayed(Duration(seconds: 0), () => controllerAppbar.forward());
    }

When i scrolled the screen and reached both condition , i get this error but i got the result what i want.

Error


════════ Exception caught by widgets library ═══════════════════════════════════
Class 'Color' has no instance method '-'.
Receiver: Instance of 'Color'
Tried calling: -(Instance of 'Color')
The relevant error-causing widget was
    AnimatedBuilder 

enter image description here

How i can fixed it ?

AppBarAnimation Widget


class AppBarAnimationColor extends StatefulWidget {

  final Duration duration;
  final AnimationController appBarAnimationController;
  AppBarAnimationColor({
   
    @required this.appBarAnimationController,
    this.duration = const Duration(seconds: 1),
  });
  @override
  AppBarAnimationColorState createState() => AppBarAnimationColorState();
}

class AppBarAnimationColorState extends State<AppBarAnimationColor>
    with SingleTickerProviderStateMixin {
  Animation<Color> appbarColor, iconColor;

  @override
  void initState() {
    super.initState();
    appbarColor = Tween<Color>(begin: Colors.transparent, end: colorPallete.primaryColor)
        .animate(widget.appBarAnimationController);
    iconColor = Tween<Color>(begin: colorPallete.primaryColor, end: colorPallete.white)
        .animate(widget.appBarAnimationController);
  }

  @override
  void dispose() {
    widget.appBarAnimationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: appbarColor,
      builder: (_, __) => AppBar(
        actions: [
          IconButton(
            icon: Icon(FontAwesomeIcons.bars),
            onPressed: () => '',
            color: iconColor.value,
          )
        ],
        elevation: 0,
        backgroundColor: appbarColor.value,
      ),
    );
  }
}

Welcome Screen

class _WelcomeScreenState extends State<WelcomeScreen>
    with TickerProviderStateMixin {
  AnimationController  _appbarAnimationController;
  @override
  void initState() {
    super.initState();
    _appbarAnimationController =
        AnimationController(vsync: this, duration: kThemeAnimationDuration);
  }

  
  @override
  void dispose() {
    _appbarAnimationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollNotification>(
      onNotification: (notification) => commonF.handleScrollNotification(
        notification,
        controllerAppbar: _appbarAnimationController,
      ),
      child: SafeArea(
        child: Scaffold(
          extendBodyBehindAppBar: true,
          body: Stack(
            fit: StackFit.expand,
            children: [
              SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    SizedBox(height: 1000),
                  ],
                ),
              ),
             Positioned(
                child: AppBarAnimationColor(
                  appBarAnimationController: _appbarAnimationController,
                ),
                top: 0,
                left: 0,
                right: 0,
              ),
            ],
          )
        ),
      ),
    );
  }
}

Logic

bool handleScrollNotification(
    ScrollNotification notification, {
    AnimationController controllerAppbar,
  }) {
    
    if (notification.metrics.pixels == notification.metrics.minScrollExtent) {
      Future.delayed(Duration(seconds: 0), () => controllerAppbar.reverse());
    } else {
      Future.delayed(Duration(seconds: 0), () => controllerAppbar.forward());
    }
    return false;
  }

Upvotes: 3

Views: 1299

Answers (1)

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27147

You are using Tween, insted of that use ColorTween. Tween is use for value changes like int, float.

appbarColor = ColorTween(begin: Colors.transparent, end: colorPallete.primaryColor)
        .animate(widget.appBarAnimationController);
    iconColor = ColorTween(begin: colorPallete.primaryColor, end: colorPallete.white)
        .animate(widget.appBarAnimationController);

Upvotes: 9

Related Questions