Flutter笔记(四):PageView-Flutter中的ViewPager

PageView

使用PageView的三种方式

  PageView({
    Key key,
    this.scrollDirection = Axis.horizontal,  //方向
    this.reverse = false,  //是否和阅读方向一样的滚动,比如中文的阅读习惯系从左往右
    PageController controller,  //控制器
    this.physics,  //页面视图如何响应用户输入
    this.pageSnapping = true,  //使用自定义滚动时禁止页面捕捉
    this.onPageChanged,  //页面切换回调
    List<Widget> children = const <Widget>[],    //页面(组件)列表,页面个数等于长度
    this.dragStartBehavior = DragStartBehavior.start,  //拖拽行为
  })

后面两种方式去除重复数据

  PageView.builder({
    //...
    @required IndexedWidgetBuilder itemBuilder,  //创建item,根据回调index返回不同页面
    int itemCount,  //item数量
    //...
  })

第三种是自定义模式

  PageView.custom({
    //...
    @required this.childrenDelegate,  //自定义模式接受一个子页面委托对象
    //...
  })

这里主要以PageView.builder介绍一下PageView的使用

1、使用

//组件使用
PageView.builder(
  itemBuilder: (context, index) {
  return Center(
    child: _getPageByIndex(index),  //每个页面展示的组件
  );
  },
  itemCount: 4, //页面数量
  onPageChanged: _onPageChange, //页面切换
  controller: _pageController, //控制器
)
//返回每个页面子组件
StatefulWidget _getPageByIndex(int index) {
  switch (index) {
    case 0:
      return HomePage();
    case 1:
      return CategoryPage();
    case 2:
      return MeiZiPage();
    case 3:
      return AccountPage();
    default:
      return HomePage();
  }
}

2、关于controller

  PageController({
    this.initialPage = 0,    //初始化选择页面
    this.keepPage = true,    //是否保持已经渲染过得页面
    this.viewportFraction = 1.0,  //每个页面应占用的视口部分。 0~1之间
  })

在是使用PageView的时候会包含一个默认的控制器

var _pageController = PageController(initialPage: 0);

控制器跳转有4个已有的方法

  • animateToPage:带动画跳转
  • jumpToPage:直接改变当前页面无动画
  • nextPage:下一页
  • previousPage:上一页

来先看看jumpToPage的效果

_pageController.jumpToPage(_selectedIndex);
jumpToPage

再看看animateToPage的效果,ps:切换时间500ms,切换效果Curves.easeInOut

_pageController.animateToPage(_selectedIndex,
          duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
animateToPage

3、PageController的viewportFraction

每个页面应占用的视口部分。 0~1之间,比如设置为0.8可以得到以下效果,直接上图是最好的解释。再加点自动播放,循环播放之类的就是一个很nice的banner,但是这里只做demo演示,讲解以下这个属性,一般在flutter中banner不这样做,这样会有很多问题,比如拖拽时停止自动,pageView嵌套等问题。Flutter的概念里一切都是组件,banner组件我推荐轮子flutter_swiper

var _pageController = PageController(initialPage: 1, viewportFraction: 0.8);
viewportFraction: 0.8

4、配合BottomNavigationBar使用

关于BottomNavigationBar的使用可以参考我之前的
Flutter笔记(一):BottomNavigationBar常见问题
PageView和BottomNavigationBar联动的完整代码如下

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  var _pageController = PageController(initialPage: 0);

  void _incrementCounter() {
    setState(() {
      _selectedIndex++;
    });
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    if (_pageController.hasClients) {
      _pageController.animateToPage(_selectedIndex,
          duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
//      _pageController.jumpToPage(_selectedIndex);
    }
  }

  void _onPageChange(int index) {
    print("_onPageChange");
    setState(() {
      _selectedIndex = index;
    });
  }

  StatefulWidget _getPageByIndex(int index) {
    switch (index) {
      case 0:
        return HomePage();
      case 1:
        return CategoryPage();
      case 2:
        return MeiZiPage();
      case 3:
        return AccountPage();
      default:
        return HomePage();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
          child: AppBar(
            backgroundColor: Colors.white,
            brightness: Brightness.light,
            title: Center(
              child: Text(
                "FlutterDemo",
              ),
            ),
          ),
          preferredSize: Size(double.infinity, 60)),
      body: PageView.builder(
        itemBuilder: (context, index) {
          return Center(
            child: _getPageByIndex(index),  //每个页面展示的组件
          );
        },
        itemCount: 4, //页面数量
        onPageChanged: _onPageChange, //页面切换
        controller: _pageController, //控制器
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      bottomNavigationBar: new BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: new Icon(IconFont.iconhome), title: new Text("首页")),
          BottomNavigationBarItem(
              icon: new Icon(IconFont.iconcategory), title: new Text("分类")),
          BottomNavigationBarItem(
              icon: new Icon(IconFont.iconpic), title: new Text("妹子")),
          BottomNavigationBarItem(
              icon: new Icon(IconFont.iconaccount), title: new Text("我的")),
        ],
        selectedItemColor: Color(0xFF4CAF50),
        unselectedItemColor: Color(0xff666666),
        type: BottomNavigationBarType.fixed,
        showUnselectedLabels: true,
        onTap: _onItemTapped,
        currentIndex: _selectedIndex,
        selectedFontSize: 12.0,
      ),
    );
  }
}

完整代码

https://github.com/leiyun1993/FlutterDemo-GankIO

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342