Flutter: проблема с прокруткой анимации прыгающей кнопки - PullRequest
0 голосов
/ 07 апреля 2020

Я хочу добавить плавные & жидкие анимации в моем приложении Flutter, особенно на кнопках , подобных этим в приложении Reflectly (также сделано для Flutter).

Итак, я следовал этому уроку , чтобы добавить Bouncing Animations на мои кнопки. Все работает нормально, но я заметил « ошибка », относящуюся к свитку:

Когда я нажимаю кнопку И продолжаю нажимать ее, затем перетащить для прокрутки вниз или вверх ( всегда удерживая нажатой ), кнопки сохраняют состояние вниз и не возвращают в исходное положение (см. GIF для получения более подробной информации).

Примечание. Эта проблема не отображается в приложении Reflecty .

bug video

Чтобы воспроизвести этот « bug », вы можете загрузить здесь проект «Отскакивающая кнопка» , а затем создать прокрутку с несколькими прыгающими кнопками. внутри него вот так:

return Scaffold(
      body: Container(
        width: double.infinity,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              AnimatedButton(),
              // [...] Many others animated button here 
            ],
          ),
        ),
      ),
    );

Я пытался добавить обратный вызов onVerticalDragEnd для восстановления состояния после, но это хуже , потому что больше невозможно прокручивать (прокрутка, кажется, ловит только кнопки)!

Любая помощь будет принята с благодарностью:)

Заранее спасибо!

1 Ответ

1 голос
/ 08 апреля 2020

Вы можете скопировать код вставки и выполнить полный код ниже
Когда onTapDown и прокрутка сработает onTapCancel
Вы можете поместить _controller.reverse(); в _onTapCancel()
фрагмент кода

void _onTapCancel() {
    print("on tap cancel");
    _controller.reverse();
  }

рабочая демоверсия

enter image description here

полный код

import 'package:flutter/material.dart';

class AnimatedButton extends StatefulWidget {
  @override
  _AnimatedButtonState createState() => _AnimatedButtonState();
}

class _AnimatedButtonState extends State<AnimatedButton>
    with SingleTickerProviderStateMixin {
  double _scale;
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 200),
      lowerBound: 0.0,
      upperBound: 0.1,
    )..addListener(() {
        setState(() {});
      });
  }

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

  void _onTapDown(TapDownDetails details) {
    _controller.forward();
  }

  void _onTapUp(TapUpDetails details) {
    print("onTapUp");
    _controller.reverse();
  }

  void _onTapCancel() {
    print("on tap cancel");
    _controller.reverse();
  }

  @override
  Widget build(BuildContext context) {
    _scale = 1 - _controller.value;

    return GestureDetector(
      onTapDown: _onTapDown,
      onTapUp: _onTapUp,
      onTapCancel: _onTapCancel,
      child: Transform.scale(
        scale: _scale,
        child: _animatedButtonUI,
      ),
    );
  }

  Widget get _animatedButtonUI => Container(
        height: 100,
        width: 250,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(100),
          boxShadow: [
            BoxShadow(
              color: Color(0x80000000),
              blurRadius: 30.0,
              offset: Offset(0.0, 30.0),
            ),
          ],
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [
              Color(0xFFA7BFE8),
              Color(0xFF6190E8),
            ],
          ),
        ),
        child: Center(
          child: Text(
            'tap!',
            style: TextStyle(
              fontSize: 30,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
        ),
      );
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: double.infinity,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
              AnimatedButton(),
            ],
          ),
        ),
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...