Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

flutter - How can I use a widget with animation several times

I've created an custom widget with animation and used it several times, but when i try to use controller.forward(); the animation works only for the last widget. But I want to the widget I clicked on to be animated, please, help how can I implement that? here is my widget:

import 'package:flutter/material.dart';
import 'package:project/colors.dart';//for colors

class Favourite extends StatefulWidget {
  final IconData icon;
  final Function function;
  final Color color;
  final Color bgColor;
  final double width;
  final double height;
  final double iconSize;
  Favourite({
    this.icon,
    this.function,
    this.color = blue,
    this.bgColor = white,
    this.height = 45,
    this.width = 45,
    this.iconSize = 40,
  });

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

AnimationController controller;

class _FavouriteState extends State<Favourite>
    with SingleTickerProviderStateMixin {
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this, // the SingleTickerProviderStateMixin
      duration: Duration(
          milliseconds: 300), // how long should the animation take to finish
      value: 0.1,
      upperBound: 1,
      lowerBound: 0.5,
    );
    animation =
        CurvedAnimation(parent: controller, curve: Curves.easeInOutCirc);
    controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller.reverse();
      }
    });
  }

  @override
  dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width,
      height: widget.height,
      margin: EdgeInsets.symmetric(horizontal: 8, vertical: 10),
      decoration: BoxDecoration(
        color: widget.bgColor,
        boxShadow: [
          BoxShadow(
            color: Colors.black26,
            blurRadius: 10,
          ),
        ],
        borderRadius: BorderRadius.all(
          Radius.circular(15),
        ),
      ),
      child: Center(
        child: ScaleTransition(
          scale: animation,
          child: IconButton(
            onPressed: widget.function,
            icon: Icon(
              widget.icon,
              color: widget.color,
              size: widget.iconSize,
            ),
          ),
        ),
      ),
    );
  }
}

By that I wanted to create a little animation for the favorite button with changing scale. Here is how I used that:

class LaptopBlock extends StatefulWidget {
  @override
  _LaptopBlockState createState() => _LaptopBlockState();
}

class _LaptopBlockState extends State<LaptopBlock> with SingleTickerProviderStateMixin{
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 380,
      child: ListView.builder(
        padding: EdgeInsets.all(25),
        scrollDirection: Axis.horizontal,
        itemCount: laptops.length,
        itemBuilder: (BuildContext context, int index) { ...
     Favourite(
      icon: laptops[index].isLiked == true
      ? Icons.favorite
      : Icons.favorite_border,
      function: () {
       setState(() {
        controller.forward();
        laptops[index].isLiked = !laptops[index].isLiked;
       });
      },
    ), ...

So when I click on the first Favourite widget the icon changes, but the animation is applied for the last one in the ListView.builder, not the one I clicked.

Couldn't find the answer in the internet, so was forced to ask here, thank you in advance and sorry for my poor English

question from:https://stackoverflow.com/questions/65600728/how-can-i-use-a-widget-with-animation-several-times

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think its because you made the AnimationController outside of the State class. Try moving it into the State class. That way you will have a different AnimationController for each instance of the Widget.

i.e

class _FavouriteState extends State<Favourite>
    with SingleTickerProviderStateMixin {
  AnimationController controller;

Instead of

AnimationController controller;

class _FavouriteState extends State<Favourite>
    with SingleTickerProviderStateMixin {

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...