Как создать карусель (скользящую анимацию) с PageView во Flutter? - PullRequest
0 голосов
/ 20 декабря 2018

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

page_indicator: ^ 0.1.3

В настоящее время я могу перемещаться между изображениями с помощью жеста смахивания с индикатором страницы, и теперь я хочу анимироватьскользит многократно с х продолжительностью.Мой код ниже.

final PageController controller = new PageController();

@override
Widget build(BuildContext context) {
List<Widget> list = new List<Widget>();
list.add(new SliderBox(image: 'assets/shirt.png'));
list.add(new SliderBox(image: 'assets/laptops.png'));
list.add(new SliderBox(image: 'assets/bags.png'));

PageIndicatorContainer container = new PageIndicatorContainer(
  pageView: new PageView(
    children: list,
    controller: controller,
  ),
  length: 3,
  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)),Text('$moveToPage')
]);


class SliderBox extends StatelessWidget {
final image;

const SliderBox({Key key, this.image}) : super(key: key);

@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
    padding: EdgeInsets.all(10),
    child: Image.asset(
      image,
      height: 300,
      fit: BoxFit.fill,
    ));
}
}

1 Ответ

0 голосов
/ 20 декабря 2018

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

  1. Сделать ваш List доступным внутри самого state, чтобы получить его длину.

  2. Создайте рекурсивный метод, который будет обрабатывать саму анимацию.

  3. Убедитесь, что вы вызываете его после визуализации первого кадра на экране, чтобы предотвратить доступ к PageController, прежде чем иметьPageView отображается на экране, что вы, вероятно, не хотите.Для этого вы используете WidgetsBinding.instance.addPostFrameCallback .

demo

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);
  }
}
...