Сначала давайте посмотрим на эффект этой статьи:
Когда мы впервые видим этот эффект, согласно нашему привычному мышлению, мы обычно делаем это:
- Перейти к ViewPager
- Настройте прослушиватели или делегаты для реагирования на события прокрутки
- Получить вид на экране, рассчитать и установить его перевод
Но во Flutter мы должны изменить свое мышление, потому что Flutter — это декларативный UI-фреймворк, и новое дерево виджетов нужно генерировать для каждого изменения кадра, поэтому нам нужно заботиться только о взаимосвязи между представлениями и представлениями, а затем, когда построение дерева виджетов. Вычисленное значение можно внести в метод построения.
Для достижения описанного выше эффекта мелкий текст Text в два раза быстрее, чем общая скорость движения, когда страница скользит, поэтому перевод X мелкого текста равен.
Здесь задействованы два основных момента: как получить размер виджета во Flutter и как контролировать прокрутку страницы.
Во-первых, нужно получить размер виджета.Поскольку все виджеты во Flutter имеют адаптивный размер, для виджета его размер должен быть как можно больше (например,PageView) или как можно меньше (например,Text), поэтому все, что мы можем получить, — это диапазон (ограничение). Чтобы получить диапазон размеров виджета, просто оберните его виджетом LayoutBuilder, например:
new LayoutBuilder(builder: (context, constraints) => new XXXWidget());
Максимальный и минимальный размер XXXWidget можно получить с помощью ограничений. Так как PageView будет максимально заполнять экран, ограничения.maxWidth — это фактическая ширина PageView во время выполнения.
Во-вторых, как получить события прокрутки.Во Flutter есть встроенный механизм уведомлений.Виджет может передать событие в верхний узел дерева виджетов через уведомление.
Метод слушателя - использовать уведомлениеNotificationListenerПакет должен контролировать подзредующее событие, а конкретный процесс использования будет описан ниже.
Flutter автоматически применит некоторые анимации и визуальные эффекты в зависимости от платформы, например, PageView создаст эффект отскока за пределы на iOS (то есть показанный в видео), а на Android покажет эффект пульсации. , Этот эффект можно указать, указав эффект просмотра прокрутки.ScrollPhysicsреализовать.
Давайте посмотрим на окончательный код:
class PageDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _PageDemoState();
}
class _PageDemoState extends State<PageDemo> {
final PageController _pageController = new PageController();
double _currentPage = 0.0;
@override
Widget build(BuildContext context) => new Scaffold(
appBar: new AppBar(
title: const Text('Page Demo'),
),
body: new LayoutBuilder(builder: (context, constraints) => new NotificationListener(
onNotification: (ScrollNotification note) {
setState(() {
_currentPage = _pageController.page;
});
},
child: new PageView.custom(
physics: const PageScrollPhysics(parent: const BouncingScrollPhysics()),
controller: _pageController,
childrenDelegate: new SliverChildBuilderDelegate(
(context, index) => new _SimplePage(
'$index',
parallaxOffset: constraints.maxWidth / 2.0 * (index - _currentPage),
),
childCount: 10,
),
),
)),
);
}
Чтобы получить прогресс прокрутки, мы можем указатьPageController,этоScrollControllerПодкласс , который используется для управления состоянием представления прокрутки. Он также предоставляет ряд свойств и методов для управления представлением прокрутки. При создании PageView вы можете вручную указать PageController, чтобы позже получить состояние PageView. .
Следует отметить, что NotificationListener не обновляет представление при вызове onNotification, поэтому нам также необходимо вызвать setState корневого представления, чтобы обновить состояние представления.
Далее реализуем карусельную страницу:
class _SimplePage extends StatelessWidget {
_SimplePage(this.data, {
Key key,
this.parallaxOffset = 0.0
}) : super(key: key);
final String data;
final double parallaxOffset;
@override
Widget build(BuildContext context) => new Center(
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(
data,
style: const TextStyle(fontSize: 60.0),
),
new SizedBox(height: 40.0),
new Transform(
transform: new Matrix4.translationValues(parallaxOffset, 0.0, 0.0),
child: const Text('Yet another line of text'),
),
],
),
),
);
}
Здесь мы можем напрямую использовать StatelessWidget, передать трансляцию элементу Transform, приняв параметры конструктора.
резюме
Из этого примера видно, что во Flutter все эффекты реализованы в декларативных методах, а методы ООП используются редко, такие методы, как setOpacity и setScale, вы вряд ли встретите. Кроме того, Flutter широко использует различные иерархии для достижения различных эффектов расширения, таких как преобразования, фильтры и ограничения размера.Эти эффекты достигаются путем обертывания слоя декоративных представлений для представления содержимого.Подробности см. на официальном сайте документации. В целом, во Flutter очень легко реализовать сложные интерфейсные эффекты.