I'm trying to animate some widgets inside PageView and created a custom AnimatedWidget which uses PageController also used by PageView. The idea is to animate some text up as user swipes through slides. The code below will throw error on the first render, once I start swiping left/right everything works but I get red screen with error initially. I tried to defend by checking controller.hasClients but there is already 1 page in the controller and error comes from assertion in PageView page getter. Is there any other prop I can check to delay animating after the first render?
import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MySlider extends StatelessWidget {
final _controller = new PageController();
final List<String> _pages = [
'Create your football profile',
'Your team, your players, your line-up',
'Track the stats that matter and share with others'
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
PageView.builder(
controller: _controller,
itemBuilder: (_, index) => Slide(
controller: _controller,
position: index,
heading: _pages[index],
),
itemCount: _pages.length,
physics: AlwaysScrollableScrollPhysics(),
),
]
)
);
}
}
class Slide extends AnimatedWidget {
final PageController controller;
final String heading;
final int position;
Slide({
this.controller,
this.heading,
this.position
}) : super(listenable: controller);
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final textYOffset = controller.hasClients
? screenHeight * (controller.page - position)
: 0;
final opacity = controller.hasClients
? 1.0 - math.max(0, controller.page - position)
: 1.0;
return Stack(
alignment: Alignment.topCenter,
children: [
Positioned(
bottom: 120,
left: 16,
right: 16,
child: Transform.translate(
offset: Offset(0, -textYOffset),
child: Opacity(
opacity: opacity,
child: Text(heading)
),
),
)
],
);
}
}
Exception in the console:
════════ Exception caught by widgets library ═════════════════════════════════════════════
The following assertion was thrown building Slide(animation:
PageController#c35ec(one client, offset 0.0), dirty, dependencies: [MediaQuery], state: _AnimatedState#05ff4):
Page value is only available after content dimensions are established. 'package:flutter/src/widgets/page_view.dart':
Failed assertion: line 373 pos 7: 'pixels == null || (minScrollExtent != null &&maxScrollExtent != null)'
minScrollExtent
at this point is 0.0 same with maxScrollExtent