Как сделать анимацию переключения двух элементов GridView во Flutter - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь сделать анимацию переключения между двумя элементами GridView во Flutter.

Я уже пробовал PositionedTransition, а также обычную анимацию с Tween.Элементы вообще не анимируются.

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomeScreenState();
  }
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        child: GridView.count(
          shrinkWrap: true,
          crossAxisSpacing: 4,
          mainAxisSpacing: 4,
          crossAxisCount: 5,
          children: List.generate(25, (index) {
            return GestureDetector(
              onVerticalDragUpdate: (drag) {
                if (drag.delta.dy > 10) print('down');
                if (drag.delta.dy < -10) print('up');
              },
              onHorizontalDragUpdate: (drag) {
                if (drag.delta.dx > 10) print('right');
                if (drag.delta.dx < -10) print('left');
              },
              onHorizontalDragEnd: /* ANIMATE NOW */,
              onVerticalDragEnd: /* ANIMATE NOW */,
              child: Container(
                decoration: BoxDecoration(
                    color: Colors.green,
                    borderRadius: BorderRadius.all(Radius.circular(5.0))
                ),
              ),
            );
          }),
        )
    );
  }

}

В идеале я хотел бы иметь возможность провести пальцем влево / вправо / вверх / вниз по элементу сетки и переключить этот элемент с соответствующим элементом рядом сэто (относительно направления движения).

1 Ответ

0 голосов
/ 25 февраля 2019

Я отказался от попыток с GridView.Однако я нашел способ получить тот же результат с помощью Stack и SlideTransition:

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomeScreenState();
  }
}

class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
  String move;
  List<Tween> _switchTween = List();
  List<Animation> _switchAnim = List();
  List<AnimationController> _switchAnimCont = List();
  double width;

  @override
  void initState() {
    // Add a tween and a controller for each element
    for (int i = 0; i < 5; i++) {
      _switchAnimCont.add(AnimationController(
        vsync: this,
        duration: const Duration(milliseconds: 100),
      ));
      _switchTween.add(Tween<Offset>(begin: Offset.zero, end: Offset(0, 1)));
      _switchAnim.add(_switchTween[i].animate(_switchAnimCont[i]));
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    width = MediaQuery.of(context).size.width/5;
    return Stack(
      children: <Widget>[
        square(0, 0, 0),
        square(1, width, 0),
        square(2, 2*width, 0),
        square(3, 3*width, 0),
        square(4, 4*width, 0),
      ],
    );
  }

  Widget square(int index, double left, double bottom) {
    return Positioned(
      left: left,
      bottom: bottom,
      width: width,
      height: width,
      child: SlideTransition(
        position: _switchAnim[index],
        child: GestureDetector(
          // Figure out swipe's direction
          onHorizontalDragUpdate: (drag) {
            if (drag.delta.dx > 10) move = 'right';
            if (drag.delta.dx < -10) move = 'left';
          },
          onHorizontalDragEnd: (drag) {
            switch(move) {
              case 'right' : {moveRight(index); break;}
              case 'left' : {moveLeft(index); break;}
            }
          },
          child: Container(
            margin: EdgeInsets.all(2),
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(Radius.circular(5.0))
            ),
          ),
        ),
      ),
    );
  }

  void moveRight(int index) {
    // Move the grid element that you swiped on
    _switchTween[index].end = Offset(1, 0);
    _switchAnimCont[index].forward();

    // Move the element next to it the opposite way
    _switchTween[index+1].end = Offset(-1, 0);
    _switchAnimCont[index+1].forward();

    // You could need to refresh the corresponding controller to animate again
  }

  void moveLeft(int index) {
    _switchTween[index].end = Offset(-1, 0);
    _switchAnimCont[index].forward();
    _switchTween[index-1].end = Offset(1, 0);
    _switchAnimCont[index-1].forward();
  }

}

Это нарисует 5 белых квадратов, и проведя пальцем влево или вправо по одному из них, соответствующий квадрат поменяется местамис одним рядом с ним.Он также может быть расширен для использования по вертикали (при условии добавления новой строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...