Flutter: запуск GestureDetector на анимированных изображениях в стеке - PullRequest
1 голос
/ 17 января 2020

У меня есть анимированный «цветок», состоящий из изображений лепестков, которые поворачиваются в положение на сборке виджета. Изображения лепестков могут быть различной длины.

Поскольку я не знал, как переместить точку поворота каждого PNG лепестка в нижний центр вращения, я сделал каждое изображение лепестка прозрачным квадратом с нижней частью. лепестка в центре изображения, так что я могу просто повернуть все квадратное изображение вокруг центра, и похоже, что лепесток вращается вокруг своей основы.

У меня есть 5 из них в стопке, анимированные , и я хочу детектор жестов на каждом из них, чтобы я мог действовать, когда любой из них коснулся. У меня уже есть GestureDetector на изображении, которое я использую для центра цветка, и это работает, но ни один из лепестков не работает.

Я попытался использовать HitTestBehavior.translucent без удачи ...

class _PFMainScreenState extends State<PFMainScreen>
    with TickerProviderStateMixin {
  AnimationController rotationController;

  @override
  void initState() {
    super.initState();
    rotationController = AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);
  }

  void onAfterBuild(BuildContext context) {
    Future.delayed(const Duration(milliseconds: 1000), () {
      rotationController.forward();
    });
  }

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

  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) => onAfterBuild(context));
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: DecoratedBox(
          position: DecorationPosition.background,
          decoration: BoxDecoration(
            color: Colors.black,
            image: DecorationImage(
                image: AssetImage('images/background.jpg'),
                fit: BoxFit.contain),
          ),
          child: Stack(
            children: <Widget>[
              Center(
                child: GestureDetector(
                    onTap: () {
                      print('1st image tapped');
                    },
                    behavior: HitTestBehavior.translucent,
                    child: Image.asset('images/petal-square.png', height: 350)),
              ),
              Center(
                child: RotationTransition(
                  turns: Tween(begin: 0.0, end: 0.2).animate(
                      new CurvedAnimation(
                          parent: rotationController,
                          curve: Curves.decelerate,
                          reverseCurve: Curves.decelerate)),
                  child: GestureDetector(
                      onTap: () {
                        print('2nd image tapped');
                      },
                      behavior: HitTestBehavior.translucent,
                      child:
                          Image.asset('images/petal-square.png', height: 250)),
                ),
              ),
              Center(
                child: RotationTransition(
                  turns: Tween(begin: 0.0, end: 0.4).animate(
                      new CurvedAnimation(
                          parent: rotationController,
                          curve: Curves.decelerate,
                          reverseCurve: Curves.decelerate)),
                  child: Image.asset('images/petal-square.png', height: 400),
                ),
              ),
              Center(
                child: RotationTransition(
                  turns: Tween(begin: 0.0, end: 0.6).animate(
                      new CurvedAnimation(
                          parent: rotationController,
                          curve: Curves.decelerate,
                          reverseCurve: Curves.decelerate)),
                  child: Image(
                    image: AssetImage('images/petal-square.png'),
                  ),
                ),
              ),
              Center(
                child: RotationTransition(
                  turns: Tween(begin: 0.0, end: 0.8).animate(
                      new CurvedAnimation(
                          parent: rotationController,
                          curve: Curves.decelerate,
                          reverseCurve: Curves.decelerate)),
                  child: Image.asset('images/petal-square.png', height: 200),
                ),
              ),
              Center(
                child: GestureDetector(
                  onTap: () {
                    //rotationController.forward(from: 0.0);
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => PFMenuScreen(),
                      ),
                    );
                  },
                  behavior: HitTestBehavior.translucent,
                  child: Image(
                    height: 100.0,
                    width: 100.0,
                    image: AssetImage('images/centre.png'),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Есть ли способ обнаружить постукивания по непрозрачным изображениям в стеке?

Приветствия

1 Ответ

0 голосов
/ 29 января 2020

Если вы запустите свое приложение с помощью инспектора флаттера Dart Dev Tools, вы увидите, что каждый из ваших Center виджетов заполняет весь экран. Это может повлиять на обнаружение вашего жеста в зависимости от того, где вы разместили детектор жестов.

Image of Flutter inspector in Dart Dev Tools

Вот код, который должен работать для вас. Я преобразовал ваше вращающееся изображение в виджет многократного использования.

class PFMainScreen extends StatefulWidget {
  @override
  _PFMainScreenState createState() => _PFMainScreenState();
}

class _PFMainScreenState extends State<PFMainScreen>
    with TickerProviderStateMixin {
  AnimationController rotationController;

  @override
  void initState() {
    super.initState();
    rotationController = AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);
  }

  void onAfterBuild(BuildContext context) {
    Future.delayed(const Duration(milliseconds: 1000), () {
      rotationController.forward();
    });
  }

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

  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) => onAfterBuild(context));
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: Stack(
          alignment: AlignmentDirectional.center,
          children: <Widget>[
            RotatingImage(
              rotationController: rotationController,
              onTap: () {
                print("Image 1 tapped");
              },
              imageHeight: 400,
              tweenEnd: 0.2,
            ),
            RotatingImage(
              rotationController: rotationController,
              onTap: () {
                print("Image 2 tapped");
              },
              imageHeight: 350,
              tweenEnd: 0.4,
            ),
            RotatingImage(
              rotationController: rotationController,
              onTap: () {
                print("Image 3 tapped");
              },
              imageHeight: 250,
              tweenEnd: 0.6,
            ),
            RotatingImage(
              rotationController: rotationController,
              onTap: () {
                print("Image 4 tapped");
              },
              imageHeight: 200,
              tweenEnd: 0.8,
            ),
          ],
        ),
      ),
    );
  }
}

class RotatingImage extends StatelessWidget {
  final AnimationController rotationController;
  final double imageHeight;
  final double tweenEnd;
  final Function onTap;
  const RotatingImage({
    this.onTap,
    this.imageHeight,
    this.tweenEnd,
    @required this.rotationController,
  });

  @override
  Widget build(BuildContext context) {
    return RotationTransition(
      turns: Tween(begin: 0.0, end: tweenEnd).animate(new CurvedAnimation(
          parent: rotationController,
          curve: Curves.decelerate,
          reverseCurve: Curves.decelerate)),
      child: GestureDetector(
          onTap: onTap,
          behavior: HitTestBehavior.translucent,
          child: Image.asset('images/petal-square.png', height: imageHeight)),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...