利用Flutter打造ViewPager(0基礎教程)

本文適合Flutter初學者,沒有過多的深入內容,一起來感受flutter的魅力吧。

在原生安卓中,viewPager還是有一定難度的,通常我們要配合fragment及adapter使用,還要去管理fragment的生命週期。代碼量還是有的。
如何在flutter裏實現ViewPager呢?
答案很簡單,flutter爲我們封裝了一個PageView的Widget,只要善用它,就可以搞定了。
先來看最簡單的情況,我們的Page均爲Image的情況,而且我們不需要監聽事件,僅僅是用戶可以滑動,展示。
先把Flutter的模版寫好。

import 'package:flutter/material.dart';

void main() {
  runApp(ViewPager());
}

class ViewPager extends StatelessWidget {
}

class ViewPagerStateful extends StatefulWidget {
}

class ViewPagerState extends State<ViewPagerStateful> {
}

順序如下,main函數創建ViewPager,ViewPager中代碼創建ViewPagerStateFul,ViewPagerStateFul中創建ViewPagerState,通過ViewPagerState改變狀態。在這裏,我們不需要改變ViewPager的狀態,所以ViewPagerStateful應該繼承於StatelessWidget。
改繼承自然要改名,於是,我們的模版如下:

import 'package:flutter/material.dart';

void main() {
  runApp(ViewPager());
}

class ViewPager extends StatelessWidget {
}

class ViewPagerStateless extends StatelessWidget {
}

根據上述的順序,我們開始往其中填寫代碼。
先填ViewPager,它就是我們的整個可見頁面。

class ViewPager extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "ViewPager",
      theme: ThemeData(primaryColor: Colors.blue),
      home: ViewPagerStateless(),
    );
  }
}

設置一個主題,幷包裹我們的ViewPagerStateless。
接下來就是重中之重了,使用PageView來創建我們的ViewPager。

class ViewPagerStateless extends StatelessWidget {
// 小米官網找的圖。嗯,來源,小米新出的cc。
  var imgs = [
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-02.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-03.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-04.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-05.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-06.png"
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ViewPager")),
      body: PageView(
        children: <Widget>[
          Image.network(imgs[0]),
          Image.network(imgs[1]),
          Image.network(imgs[2]),
          Image.network(imgs[3]),
          Image.network(imgs[4]),
        ],
      ),
    );
  }
}

appBar用來設置標題欄。
Image.network的命名構造方法可以直接幫我們把網絡的圖片下載並顯示出來。
PageView也很容易,設置一下children的list,就可以顯示了。
目前的完整代碼如下:

import 'package:flutter/material.dart';

void main() {
  runApp(ViewPager());
}

class ViewPager extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "ViewPager",
      theme: ThemeData(primaryColor: Colors.blue),
      home: ViewPagerStateless(),
    );
  }
}

class ViewPagerStateless extends StatelessWidget {
  var imgs = [
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-02.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-03.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-04.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-05.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-06.png"
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ViewPager")),
      body: PageView(
        children: <Widget>[
          Image.network(imgs[0]),
          Image.network(imgs[1]),
          Image.network(imgs[2]),
          Image.network(imgs[3]),
          Image.network(imgs[4]),
        ],
      ),
    );
  }
}

run起來效果如下:
在這裏插入圖片描述
這時候,我們已經可以左右的滑動了,也會有回彈的效果。
當然了,我們肯定不能滿足這樣的一個靜態效果,所以,我們把ViewPagerStateless刪除掉,建立ViewPagerStateful。
在Flutter中,StatefulWidget是有狀態的小部件,StatelessWidget是無狀態的小部件,有狀態的小部件才能更新哦。

class ViewPagerStateful extends StatefulWidget {
  @override
  ViewPagerState createState() {
    return ViewPagerState();
  }
}

這是有狀態小部件標準寫法了。所有的信息,都存在於ViewPagerState中。
我們還是先來實現跟之前ViewPagerStateless一樣的效果。

class ViewPagerState extends State<ViewPagerStateful> {
  var imgs = [
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-02.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-03.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-04.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-05.png",
    "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-06.png"
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ViewPager")),
      body: PageView(
        children: <Widget>[
          Image.network(imgs[0]),
          Image.network(imgs[1]),
          Image.network(imgs[2]),
          Image.network(imgs[3]),
          Image.network(imgs[4]),
        ],
      ),
    );
  }
}

run一下,就發現,跟之前的效果完全一樣。
接下來,我們要進行事件的監聽,和viewpager內容的更改。
翻看上面代碼發現,多數均爲模版代碼,僅有ViewPagerState內有很多內容。
所以,理所當然,點擊事件也要在ViewPagerState中處理。
在ViewPagerState中新建方法,用來處理點擊:
這裏要用setState這個Flutter提供給我們的用於變更數據的方法,若不寫這個包裹,則變化無效。

void changeImg(int pos) {
    setState(() {
      imgs[pos] = "https://i1.mifile.cn/f/i/2019/micc9/summary/specs-08.png";
    });
}

在ViewPagerState中新建方法,用於監聽滑動頁面變更:

void onPageChanged(int pos) {
	print("當前是第$pos頁");
}

接下來,改造ViewPagerState的build方法,用於關聯起來。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("ViewPager")),
      body: PageView(
        children: <Widget>[
          Image.network(imgs[0]),
          Image.network(imgs[1]),
          Image.network(imgs[2]),
          Image.network(imgs[3]),
          GestureDetector(
              onTap: () => changeImg(4), child: Image.network(imgs[4]))
        ],
        onPageChanged: onPageChanged,
      ),
    );
  }

這裏說一下爲什麼要用() =>這個是dart語法,若不用,則相當於直接執行changeImg(4),這樣會在我們並沒有點擊時就會調用,這是不符合要求的。
Image本身不含有點擊事件,需要用GestureDetector包裹。
這時候就可以run了。當我們切換頁面,log就會打印出來,點擊最後一頁的圖片就會更新圖片。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章