Как получить доступ к контроллеру анимации виджета Stateful из другого виджета во Flutter? - PullRequest
1 голос
/ 22 января 2020

Я хочу, чтобы виджет счетчика показывал onTap из дома widget. Кроме того, запускайте animation с начала при каждом нажатии.

Виджет счетчика

class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> with SingleTickerProviderStateMixin {
  AnimationController animationController;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 1000),
    )
      ..addListener(() => setState(() {}));

    animation = CurvedAnimation(
      parent: animationController,
      curve: Curves.elasticOut,
    );

    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(
      child: Container(
        height: 100,
        width: 100,
        color: Colors.blue,
      ),
      scale: animation,
    );
  }
}

Домашний виджет

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: <Widget>[
        Center(
          child: Counter(),
        ),
        GestureDetector(
          onTap: () {},
          child: Container(
            width: double.infinity,
            height: double.infinity,
          ),
        ),
      ],
    ));
  }

1 Ответ

1 голос
/ 22 января 2020

Вам нужно определить GlobalKey и передать его дочернему виджету. Это позволит вам получить доступ к методам и переменным этого ребенка:

class HomeWidget extends StatefulWidget {
  @override
  _HomeWidgetState createState() => _HomeWidgetState();
}

class _HomeWidgetState extends State<HomeWidget> {
  GlobalKey<CounterState> counterKey = GlobalKey<CounterState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Center(
            child: Counter(key: counterKey),
          ),
          GestureDetector(
            behavior: HitTestBehavior.translucent,
            onTap: () {
              counterKey.currentState.animationController.reverse();
            },
            child: Container(
              width: double.infinity,
              height: double.infinity,
            ),
          ),
        ],
      )
    );
  }
}


class Counter extends StatefulWidget {
  Counter({Key key}): super(key: key);

  // This state must be public in order to access it.
  @override
  CounterState createState() => CounterState();
}

class CounterState extends State<Counter> with SingleTickerProviderStateMixin {
  AnimationController animationController;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 1000),
    )
      ..addListener(() => setState(() {}));

    animation = CurvedAnimation(
      parent: animationController,
      curve: Curves.elasticOut,
    );

    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(
      child: Container(
        height: 100,
        width: 100,
        color: Colors.blue,
      ),
      scale: animation,
    );
  }
}
...