8、 Flutter Widgets 之 PageView

构造方法以及参数:

  PageView({
    Key? key,
    this.scrollDirection = Axis.horizontal, // 设置滚动方向 垂直 / 水平 
    this.reverse = false,	// 反向滚动 
    PageController? controller,	// 滚动控制类 
    this.physics,	// 滚动逻辑 , 不滚动 / 滚动 / 滚动到边缘是否反弹 
    this.pageSnapping = true,	// 如果设置 false , 则无法进行页面手势捕捉 
    this.onPageChanged, 	// 页面切换时回调该函数 
    List children = const [],
    this.dragStartBehavior = DragStartBehavior.start,
    this.allowImplicitScrolling = false,
    this.restorationId,
    this.clipBehavior = Clip.hardEdge,
  }) : assert(allowImplicitScrolling != null),
       assert(clipBehavior != null),
       controller = controller ?? _defaultPageController,
       childrenDelegate = SliverChildListDelegate(children),
       super(key: key);

基本用法

PageView控件可以实现一个“图片轮播”的效果,PageView不仅可以水平滑动也可以垂直滑动,简单用法如下:

PageView(
      children: [
        Container(color: Colors.red,),
        Container(color: Colors.black,),
        Container(color: Colors.yellow,),
      ],
    );

左右滑动效果:

8、 Flutter Widgets 之 PageView_第1张图片

 PageView滚动方向默认是水平,可以设置其为垂直方向:

PageView(
    scrollDirection: Axis.vertical,
    ...
)

PageView配合PageController可以实现非常酷炫的效果,控制每一个Page不占满,

Container(

      height:200 ,
      child: PageView(

        scrollDirection: Axis.horizontal,
        controller: PageController(viewportFraction: 0.9),
        children: [
          Container(color: Colors.red,),
          Container(color: Colors.black,),
          Container(color: Colors.yellow,),
        ],
      ),
    );

8、 Flutter Widgets 之 PageView_第2张图片

PageController中属性initialPage表示当前加载第几页,默认第一页。

onPageChanged属性是页面发生变化时的回调,用法如下:

8、 Flutter Widgets 之 PageView_第3张图片

无限滚动 

PageView滚动到最后时希望滚动到第一个页面,这样看起来PageView是无限滚动的:

List pageList = [PageView1(), PageView2(), PageView3()];

PageView.builder(
    itemCount: 10000,
    itemBuilder: (context, index) {
        return pageList[index % (pageList.length)];
    },
)

 8、 Flutter Widgets 之 PageView_第4张图片

 实现指示器

指示器显示总数和当前位置,通过onPageChanged确定当前页数并更新指示器。 

 int _currentPageIndex = 0;
  List pageList = [ Container(color: Colors.red,),
    Container(color: Colors.black,),
    Container(color: Colors.yellow,),];

 _buildPageView(){
    return Center(
      child: Container(
        height: 230,
        child: Stack(
          children: [
            PageView.builder(itemBuilder: (context,index){
              var val = pageList[index%(pageList.length)];
              print(val);
              return _buildPageViewItem('${val}');
            }),
            Positioned(
                bottom: 20,
                left: 0,
                right: 0,
                child: Container(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: List.generate(pageList.length, (i){
                      return Container(
                        margin: EdgeInsets.symmetric(horizontal: 5),
                        width: 10,
                        height: 10,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          color: _currentPageIndex==i?Colors.blue:Colors.grey
                        ),
                      );
                    }).toList(),
                  ),
                )
            )
          ],
        ),
      ),
    );
  }
  _buildPageViewItem(String txt,{Color color=Colors.red}){
    return Container(
      color: color,
      alignment: Alignment.center,
      child: Text(txt,style: TextStyle(color: Colors.white,fontSize: 25),),
    );
  }

 8、 Flutter Widgets 之 PageView_第5张图片

 切换动画

如此常见的切换效果显然不能体验我们独特的个性,我们需要更炫酷的方式,看下面的效果:8、 Flutter Widgets 之 PageView_第6张图片 

在滑出的时候当前页面逐渐缩小并居中,通过给PageController添加监听获取当前滑动的进度: 

_pageController.addListener(() {
      setState(() {
        _currPageValue = _pageController.page;
      });
    });
/**
 * @Author wywinstonwy
 * @Date 2021/12/27 9:50 下午
 * @Description:
 */
import 'package:demo202112/utils/common_appbar.dart';
import 'package:flutter/material.dart';

class WyPageView1 extends StatefulWidget {
  const WyPageView1({Key? key}) : super(key: key);

  @override
  _WyPageViewState createState() => _WyPageViewState();
}

class _WyPageViewState extends State {
  int _currentPageIndex = 0;
  var imgList = [
    'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2877516247,37083492&fm=26&gp=0.jpg',
    'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1582796218195&di=04ce93c4ac826e19067e71f916cec5d8&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F344fda8b47808261c946c81645bff489c008326f15140-koiNr3_fw658'
  ];
  late PageController _pageController;
  var _currPageValue=0;
  //缩放系数
  double _scaleFactor = .8;
  //view page height
  double _height = 230.0;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _pageController=PageController(viewportFraction: 0.9);
    _pageController.addListener(() {
      setState(() {
        _currPageValue = _pageController.page;
      });
    });

  }
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _pageController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: getAppBar('PageView'),
      body: Container(
          height: _height,
          child: PageView.builder(
            itemBuilder: (context, index) => _buildPageItem(index),
            itemCount: 10,
            controller: _pageController,
          )),
    );
  }
  _buildPageItem(int index) {
    Matrix4 matrix4 = Matrix4.identity();
    if (index == _currPageValue.floor()) {
      //当前的item
      double currScale = (1 - (_currPageValue - index) * (1 - _scaleFactor)).toDouble();
      var currTrans = _height * (1 - currScale) / 2;

      matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
        ..setTranslationRaw(0.0, currTrans, 0.0);
    } else if (index == _currPageValue.floor() + 1) {
      //右边的item
      var currScale =
          _scaleFactor + (_currPageValue - index + 1) * (1 - _scaleFactor);
      var currTrans = _height * (1 - currScale) / 2;

      matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
        ..setTranslationRaw(0.0, currTrans, 0.0);
    } else if (index == _currPageValue.floor() - 1) {
      //左边
      var currScale = (1 - (_currPageValue - index) * (1 - _scaleFactor)).toDouble();
      var currTrans = _height * (1 - currScale) / 2;

      matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0)
        ..setTranslationRaw(0.0, currTrans, 0.0);
    } else {
      //其他,不在屏幕显示的item
      matrix4 = Matrix4.diagonal3Values(1.0, _scaleFactor, 1.0)
        ..setTranslationRaw(0.0, _height * (1 - _scaleFactor) / 2, 0.0);
    }

    return Transform(
      transform: matrix4,
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 10),
        child: Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(12),
            image: DecorationImage(
                image: NetworkImage(imgList[index % 2]), fit: BoxFit.fill),
          ),
        ),
      ),
    );
  }

}

你可能感兴趣的:(Flutter,flutter,ios,android)