美文网首页
Flutter的PageView组件

Flutter的PageView组件

作者: 渣渣曦 | 来源:发表于2020-09-07 19:16 被阅读0次

基本用法

PageView可以实现组件滑动效果。不仅可以水平滑动而且可以进行垂直滑动,简单使用如下:

PageView(
    children: [
        MyPage1(),    
        MyPage2(), 
        MyPage3(),    
    ],
)
467322-20200229105341388-706954813.gif

PageView默认为水平(horizontal)滑动,如果变更为垂直滑动效果设置以下参数:

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

PageView的页面控制器(controller)可以实现多种特效,通过以下参数控制页面占比:

PageView(
    controller: PageController(
        initialPage: 0,
        viewportFraction: 0.9,
    ),
    ...
)
image.png
PageView页面控制器的initialPage是当前加载页面,默认第一页。
onPageChanged属性为页面变化后的回调函数,用法如下:
PageView(
    onPageChanged: (int index){
    },
    ...
)

无限循环

当PageView的页面滑动到最后时再重新返回第一个页面时,代码如下:

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

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

加入indicator

indicator展示显示总数的当前位置,通过onPageChanged获取当前页数并更新indicator。

List pageList = ['PageView1', 'PageView2', 'PageView3'];
  int _currentPageIndex = 0;

  _buildPageView() {
    return Center(
      child: Container(
        height: 230,
        child: Stack(
          children: [
            PageView.builder(
              onPageChanged: (int index) {
                setState(() {
                  _currentPageIndex = index % (pageList.length);
                });
              },
              itemCount: 10000,
              itemBuilder: (context, index) {
                return _buildPageViewItem(pageList[index % (pageList.length)]);
              },
            ),
            Positioned(
              bottom: 10,
              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: 28),
      ),
    );
  }

效果如下:


467322-20200229105349433-497229952.gif

切换动画

一般的切换效果不足以体现出个性化界面。制作一个更独特的效果如下:
图片上传不成功
当水平滑出时,当前页面缩小并边缘化。当前page控制器获取当前页并赋值

_pageController.addListener(() {
      setState(() {
        _currPageValue = _pageController.page;
      });
    });

完整代码如下:

class _ViewPageState extends State {
  var imgList = [
    'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2877516247,37083492&fm=26&gp=0.jpg',
    'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2877516247,37083492&fm=26&gp=0.jpg'
  ];
  PageController _pageController;

  var _currPageValue = 0.0;

  //Scaling factor
  double _scaleFactor = .8;

  //view page height
  double _height = 230.0;

  @override
  void initState() {
    super.initState();
    _pageController = PageController(viewportFraction: 0.9);
    _pageController.addListener(() {
      setState(() {
        _currPageValue = _pageController.page;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Container(
        height: _height,
        child: PageView.builder(
          itemBuilder: (context, index) => _buildPageItem(index),
          itemCount: 10,
          controller: _pageController,
        ));
  }

  _buildPageItem(int index) {
    double value;
    if (_pageController.position.haveDimensions) {
      value = _pageController.page - index;
    } else {
      // If haveDimensions is false, use _currentPage to calculate value.
      value = (_currPageValue - index).toDouble();
    }
    // We want the peeking cards to be 160 in height and 0.38 helps
    // achieve that.
    value = (1 - (value.abs() * .38)).clamp(0, 1).toDouble();
    return Transform(
      // transform: matrix4,
      transform: Matrix4.diagonal3Values(1.0, value, 1.0),
      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的PageView组件

      本文链接:https://www.haomeiwen.com/subject/peylektx.html