Я пытаюсь анимировать виджеты в своем приложении в зависимости от прокрутки пользователя и положения внутри моего виджета прокрутки ( CustomScrollView
).
До сих пор я достиг чего-то, что выглядит очень хорошо, используя метод, который я покажу ниже, но я боюсь, что этот конкретный метод:
- Это не самая эффективная с точки зрения производительности и ресурсов.
- Это не самый плавный и результат неживой анимации.
- Не будет соответствовать всем устройствам и разрешениям.
Вот что я хочу достичь, обратите внимание на положение текста и индикатор прокрутки страницы в нижнем левом углу:
Я достиг этого, выполнив следующие шаги:
-
Создание функции ( _offsetPosition
), которая получает текущее смещение, индекс страницы, к которой относится виджет, размеры порта-порта устройства и коэффициент, который я использую для ускорения или замедления анимации. Функция вернет значение от -1.0 до 1.0, а -1.0 - до того, как страница появится до момента, когда она появится на экране 1.0, только когда она исчезнет, ??а 0.0 - точно, когда страница заполняет мой порт просмотра.
-
Используйте эту функцию внутри слушателя для ScrollController
изменения и изменения значения переменной в соответствии с прокруткой и другими константами, которые я определяю, чтобы они менялись в соответствии с моими потребностями.
-
Использование этой переменной как 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
параметра?