Я немного изменил ваш виджет, чтобы предоставить вам полный пример.Вы можете сделать это несколькими способами, с помощью AnimationController отдельно или даже в сочетании с пользовательской Animation , или вы можете пойти самым быстрым путем к тому, чего вы хотите достичь: используярекурсивный метод, который ожидает длительность топора (время на отдельной странице), а затем анимирует с новой продолжительностью новую страницу.Для этого вы можете, например:
Сделать ваш List
доступным внутри самого state
, чтобы получить его длину.
Создайте рекурсивный метод, который будет обрабатывать саму анимацию.
Убедитесь, что вы вызываете его после визуализации первого кадра на экране, чтобы предотвратить доступ к PageController
, прежде чем иметьPageView
отображается на экране, что вы, вероятно, не хотите.Для этого вы используете WidgetsBinding.instance.addPostFrameCallback .

class Carousel extends StatefulWidget {
_CarouselState createState() => _CarouselState();
}
class _CarouselState extends State<Carousel> with SingleTickerProviderStateMixin {
final PageController _controller = PageController();
List<Widget> _list = [
SliderBox(
child: FlutterLogo(
colors: Colors.red,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.green,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.blue,
))
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _animateSlider());
}
void _animateSlider() {
Future.delayed(Duration(seconds: 2)).then((_) {
int nextPage = _controller.page.round() + 1;
if (nextPage == _list.length) {
nextPage = 0;
}
_controller
.animateToPage(nextPage, duration: Duration(seconds: 1), curve: Curves.linear)
.then((_) => _animateSlider());
});
}
@override
Widget build(BuildContext context) {
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: _list,
controller: _controller,
),
length: _list.length,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(
children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(color: Colors.white, child: container, margin: EdgeInsets.only(bottom: 50)),
],
);
}
}
class SliderBox extends StatelessWidget {
final Widget child;
const SliderBox({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(padding: EdgeInsets.all(10), child: child);
}
}