Анимация позиций виджетов при прокрутке

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

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

  1. Это не самая эффективная с точки зрения производительности и ресурсов.
  2. Это не самый плавный и результат неживой анимации.
  3. Не будет соответствовать всем устройствам и разрешениям.

Вот что я хочу достичь, обратите внимание на положение текста и индикатор прокрутки страницы в нижнем левом углу:

Анимация

Я достиг этого, выполнив следующие шаги:

  1. Создание функции ( _offsetPosition), которая получает текущее смещение, индекс страницы, к которой относится виджет, размеры порта-порта устройства и коэффициент, который я использую для ускорения или замедления анимации. Функция вернет значение от -1.0 до 1.0, а -1.0 - до того, как страница появится до момента, когда она появится на экране 1.0, только когда она исчезнет, ??а 0.0 - точно, когда страница заполняет мой порт просмотра.

  2. Используйте эту функцию внутри слушателя для ScrollControllerизменения и изменения значения переменной в соответствии с прокруткой и другими константами, которые я определяю, чтобы они менялись в соответствии с моими потребностями.

  3. Использование этой переменной как Paddingдля моего виджета (или для любого другого параметра, Opacityнапример).

Вот _offsetPositionфункция:

double _offsetPosition(double currentOffset, int pageIndex,
    double viewportDimension, double coefficient) {
  // Returns a value between -1.0 (left edge and before) to 1.0 (right edge and after).
  // 1.0 when the page fills the viewport exactly.
  // Making sure the return value won't be below -1.0 or 1.0 to avoid errors.
  double position = (currentOffset - pageIndex * viewportDimension) *
      coefficient /
      viewportDimension;

  if (position <= -1.0) {
    return -1.0;
  } else if (position >= 1.0) {
    return 1.0;
  } else {
    return position;
  }
}

Это - слушатель i, определяющий внутри меня, initStateчтобы изменить значения переменных и buildэкрана при его изменении:

void initState() {
  super.initState();

  _scrollController.addListener(() {
    setState(() {
      _pagePosition = _scrollController.offset /
          _scrollController.position.viewportDimension;

      _bg1Parallax = 0.2 -
          _offsetPosition(_scrollController.offset, 0,
                  _scrollController.position.viewportDimension, 1.0) *
              0.4;

      _bg2Parallax = 0.2 -
          _offsetPosition(_scrollController.offset, 1,
                  _scrollController.position.viewportDimension, 1.0) *
              0.4;

      _text1Padding = _offsetPosition(_scrollController.offset, 0,
              _scrollController.position.viewportDimension, 1.0) *
          1000.0;

      _text1Opacity = max(
          0.0,
          1.0 -
              _offsetPosition(_scrollController.offset, 0,
                      _scrollController.position.viewportDimension, 3.0)
                  .abs());
    });
  });
}

И вот пример для виджетов текста и значков, которые перемещаются, когда пользователь прокручивает, так как значение _pagePositionи _text1Paddingувеличивается, когда пользователь прокручивает вперед и наоборот:

Значок виджета:

new Padding(
  padding:
      new EdgeInsets.only(left: _pagePosition * 20.0),
  child: new Padding(
    padding: new EdgeInsets.all(0.0),
    child: new Icon(
      FontAwesomeIcons.circle,
      size: 15.0,
      color: Colors.white,
    ),
  ),
)

Текстовый виджет:

new Padding(
  padding: new EdgeInsets.only(bottom: _text1Padding),
  child: new Center(
    child: new Opacity(
      opacity: _text1Opacity,
      child: new Text(
        'Text',
        style: new TextStyle(
            fontSize: 100.0, color: Colors.white),
      ),
    ),
  ),
)

TL; DR

Должен ли я анимировать позицию виджетов, используя значение, которое изменяется в соответствии с ScrollControllerсмещением в качестве Paddingпараметра?

android,animation,dart,flutter,

0

Ответов: 1


0

Вы пытались запустить приложение в режиме деблокирования, на реальном устройстве?

В общем случае не должно возникнуть проблемы с восстановлением дерева виджета при изменении положения прокрутки, потому что Flutter был создан для эффективного управления (базовое тяжелое RenderObjectдерево не перестраивается).

Альтернативным подходом было бы использование пользовательских RenderSlivers, как показано в приложении примера flutter_gallery . Вы можете загрузить приложение в Google Play (в приложении выберите «Исследования»> «Анимация»).

Я записал видео с анимацией: https://i.imgur.com/Pj9x09q.mp4

андроид, анимация, дартс, флаттер,
Похожие вопросы
Яндекс.Метрика