Как сделать жестовую анимацию во Флаттере? - PullRequest
3 голосов
/ 13 января 2020

Я новичок в Flutter, и в настоящее время я пытаюсь сделать поворотную нижнюю панель, которая анимирует непрозрачность некоторого текста (только сейчас).

Это в основном анимация, которую я пытаюсь достичь

enter image description here

Я нашел этот ответ Саед Набиль , который создает нижний лист и получает его положение.

Как я могу анимировать Text в соответствии с процентом дража?

Ответы [ 2 ]

2 голосов
/ 13 января 2020

Основываясь на ответе Саэда Набила, я несколько раз настраивал его образец, используя TextStyle.lerp, чтобы получить текстовый стиль в соответствии с перетаскиваемой позицией.

StreamController<double> controller = StreamController.broadcast();

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

const defaultTextStyle = TextStyle(
  color: Colors.blue,
  fontSize: 15,
);

class _MyWidgetState extends State<MyWidget> {
  double position;
  TextStyle textStyle = defaultTextStyle;

  @override
  Widget build(BuildContext context) {
    final maxPosition = MediaQuery.of(context).size.height - 300;
    return Container(
      child: Center(
        child: RaisedButton(
            child: Text('Show Buttom Sheet'),
            onPressed: () {
              showModalBottomSheet(
                  isScrollControlled: true,
                  context: context,
                  builder: (context) {
                    return StreamBuilder(
                      stream: controller.stream,
                      builder: (context, snapshot) => GestureDetector(
                          onVerticalDragUpdate: (DragUpdateDetails details) {
                            position = MediaQuery.of(context).size.height -
                                details.globalPosition.dy;
                            double newPosition = position;
                            if (position.isNegative || position == 0)
                              Navigator.pop(context);
                            else {
                              if (position > maxPosition) {
                                newPosition = maxPosition;
                              }
                              controller.add(newPosition);
                            }

                            textStyle = TextStyle.lerp(
                                defaultTextStyle,
                                TextStyle(
                                  color: Colors.black,
                                  fontSize: 24,
                                ),
                                newPosition / maxPosition);
                          },
                          behavior: HitTestBehavior.translucent,
                          child: Container(
                            color: Colors.white,
                            height: snapshot.hasData ? snapshot.data : 50.0,
                            width: double.infinity,
                            child: Text(
                              'Reviews',
                              style: textStyle,
                              textAlign: TextAlign.center,
                            ),
                          )),
                    );
                  });
            }),
      ),
    );
  }
}

Результат

enter image description here

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

В зависимости от того, какое решение вы используете для своего модального нижнего листа, вы сможете выделить переменную, которая меняется в зависимости от листа. Обычно это достигается с помощью controller, который предоставляют некоторые виджеты, или, в случае с Saed Nabil, он передает эту переменную в пользовательскую.

Пока у вас есть переменная, вы должны иметь возможность предоставлять простую математику для виджета Opacity поверх вашего текстового виджета с чем-то вроде этого.

Предполагая, что ваша переменная имеет значение 0, 0,1, 0,111 0,222 ..... 1. Вы можете сделать что-то вроде этого:

double opacity = 1 - controller.position;

Opacity(
  opacity: opacity,
  child: Text(),
);
...