flutter學習五:實現輪播圖Swiper、GridView佈局、點擊事件,ListView組裝佈局

好久沒有自學flutter,有點落下,現在有空就抓緊補上,如標題所示,這篇博文是實現輪播圖Swiper、GridView的組合佈局及各自的點擊事件,最後是將它們抽出方法來,而不是全部寫在build裏面,不然代碼看起來不舒服而且不易維護。我自己摸索了一個上午,一邊調試一邊查閱資料,最後實現後,整理好代碼就寫這篇博文了。效果圖如下所示(湊齊六宮格,重點後面一排):

                                

 

                                

 

 說明:代碼出現的自定義字體、使用本地圖片,你可以不用它(圖片換成網絡的),如果你想用可是又不會用,可以看前面的flutter學習二(裏面有涉及怎麼使用本地圖片)、flutter學習四(字體)。

一. 輪播圖: 

1. 在看代碼之前,先添加swiper包,在pubspec.yaml裏面添加如下圖(按照提示依次操作):

 

 

 2. 操作1後可以看如下代碼了,關於用到的屬性解釋,我是根據自己的理解來備註的,網上有更多的屬性及詳細的說明,你可以網上查找,我這裏就詳細說了:

注:代碼必須寫在Widget build(BuildContext context)前面,getDialog( )是顯示dialog的一個方法,後面會給出相關代碼。

  //本地圖片,也可以使用網絡圖片
  static List imageList = [
    'images/lake.jpg',
    'images/lake.jpg',
    'images/lake.jpg'
  ];

Container(
    //輪播圖的高度
    height: 120,
    //輪播圖,還有其它的屬性,這裏不一一介紹了
    child: Swiper(
      //有多少個
      itemCount: imageList.length,
      //是否自動滾動
      autoplay: true,
      //滾動的放心,左右、上下(默認左右)
      scrollDirection: Axis.horizontal,
      //用戶滑動輪播圖時是否停止自動播放
      autoplayDisableOnInteraction: true,
      itemBuilder: (BuildContext context, int index) {
        return Image.asset(
          //顯示imageList裏面的圖片、imageList是網絡圖片時用Image.network
          imageList[index],
          fit: BoxFit.fill, //填充方式
        );
      },
      //輪播改變時調用的(用戶操作或者自動輪播)
      onIndexChanged: (index) {
        //相應的操作,一般也不操作
      },
      //點擊某個輪播圖
      onTap: (index) {
        showDialog(
          context: context1,
          barrierDismissible: true, //點擊彈窗外部是否消失
          child: getDialog("您點擊了第:$index個輪播圖"), //dialog顯示點擊的內容
        );
      },
      //顯示指示器,SwiperPagination()是默認,可以在裏面修改位置、距離、樣式
      pagination: SwiperPagination(
        alignment: Alignment.bottomCenter, //指示器的位置
        margin: const EdgeInsets.only(bottom: 10), //瑜邊框的距離
        builder: SwiperPagination.dots, //指示器的樣式:dots點、fraction數字
      ),
    ),
  );

二. GridView的顯示、點擊事件及顯示dialog:

 注:代碼必須寫在Widget build(BuildContext context)前面

   //顯示的數據
  static List chainList = ['武漢', '加油!', '中國', '加油!', '我們', '必勝!'];

Container(
    child: GridView.count(
      shrinkWrap: true,
      //解決listView嵌套GridView不能滾動問題
      physics: new NeverScrollableScrollPhysics(),
      //水平之間的間距
      crossAxisSpacing: 10.0,
      //垂直之間的間距
      mainAxisSpacing: 30.0,
      //GridView內邊距,all四個方向
      padding: EdgeInsets.all(10.0),
      //一行顯示多少個Widget
      crossAxisCount: 1,
      //Widget寬高比例
      childAspectRatio: 2.0,
      //數據
      children: getGridList(),
    ),
  );


  //獲取GridView顯示的數據,及設置子item的樣式
  static List<Widget> getGridList() {
    return chainList.map((item) => getItemContainer(item)).toList();
  }


  //每個GridView裏面的item設置
  static Widget getItemContainer(String item) {
    return new GestureDetector(
      //點擊事件  onTap輕按
      onTap: () {
        showDialog(
          context: context1,
          barrierDismissible: true, //點擊彈窗外部是否消失
          child: getDialog(item), //dialog顯示點擊的內容
        );
      },
      child: new Container(
        height: 80,
        margin: EdgeInsets.only(bottom: 5),
        alignment: Alignment.center,
        decoration: BoxDecoration(color: Colors.red),
        child: Text(
          item,
          style: TextStyle(color: Colors.white, fontSize: 20),
        ),
      ),
    );
  }

三. 在build裏面Swiper、GridView進行組合,更多的摸索的時間花在這裏了,裏面涉及到ListView嵌套GridView:

注:這樣子組合,把對應分wigdet進行封裝,而不是全部佈局寫在body: Center裏面,是不是簡潔好看多了,而且也方便管理

 new ListView(
        shrinkWrap: true,
        children: <Widget>[
          swiperSection,
          gridSection,
        ],
      ),

四. 完整代碼:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';

class HomeScreen extends StatelessWidget {
  //自定義字體
  final textStyle = const TextStyle(
    fontFamily: 'Chu',
    color: Colors.red,
    fontSize: 20,
  );

  //用於路由(就是界面的跳轉),當跳轉的事件沒有寫在build裏面時用到(我這裏抽到了loginButton裏面)
  static BuildContext context1;

  //本地圖片,也可以使用網絡圖片
  static List imageList = [
    'images/lake.jpg',
    'images/lake.jpg',
    'images/lake.jpg'
  ];

  static List chainList = ['武漢', '加油!', '中國', '加油!', '我們', '必勝!'];

  //輪播圖控件,寫在build的前面,Container創建矩形視覺元素,可對元素進行修飾eg:背景色、邊框、邊距、填充等
  static Widget swiperSection = new Container(
    //輪播圖的高度
    height: 120,
    //輪播圖,還有其它的屬性,這裏不一一介紹了
    child: Swiper(
      //有多少個
      itemCount: imageList.length,
      //是否自動滾動
      autoplay: true,
      //滾動的放心,左右、上下(默認左右)
      scrollDirection: Axis.horizontal,
      //用戶滑動輪播圖時是否停止自動播放
      autoplayDisableOnInteraction: true,
      itemBuilder: (BuildContext context, int index) {
        return Image.asset(
          //顯示imageList裏面的圖片、imageList是網絡圖片時用Image.network
          imageList[index],
          fit: BoxFit.fill, //填充方式
        );
      },
      //輪播改變時調用的(用戶操作或者自動輪播)
      onIndexChanged: (index) {
        //相應的操作,一般也不操作
      },
      //點擊某個輪播圖
      onTap: (index) {
        showDialog(
          context: context1,
          barrierDismissible: true, //點擊彈窗外部是否消失
          child: getDialog("您點擊了第:$index個輪播圖"), //dialog顯示點擊的內容
        );
      },
      //顯示指示器,SwiperPagination()是默認,可以在裏面修改位置、距離、樣式
      pagination: SwiperPagination(
        alignment: Alignment.bottomCenter, //指示器的位置
        margin: const EdgeInsets.only(bottom: 10), //瑜邊框的距離
        builder: SwiperPagination.dots, //指示器的樣式:dots點、fraction數字
      ),
    ),
  );

  //GridView控件
  static Widget gridSection = new Container(
    child: GridView.count(
      shrinkWrap: true,
      //解決listView嵌套GridView不能滾動問題
      physics: new NeverScrollableScrollPhysics(),
      //水平之間的間距
      crossAxisSpacing: 10.0,
      //垂直之間的間距
      mainAxisSpacing: 30.0,
      //GridView內邊距,all四個方向
      padding: EdgeInsets.all(10.0),
      //一行顯示多少個Widget
      crossAxisCount: 1,
      //Widget寬高比例
      childAspectRatio: 2.0,
      //數據
      children: getGridList(),
    ),
  );

  //獲取GridView顯示的數據,及設置子item的樣式
  static List<Widget> getGridList() {
    return chainList.map((item) => getItemContainer(item)).toList();
  }

  //每個GridView裏面的item設置
  static Widget getItemContainer(String item) {
    return new GestureDetector(
      //點擊事件  onTap輕按
      onTap: () {
        showDialog(
          context: context1,
          barrierDismissible: true, //點擊彈窗外部是否消失
          child: getDialog(item), //dialog顯示點擊的內容
        );
      },
      child: new Container(
        height: 80,
        margin: EdgeInsets.only(bottom: 5),
        alignment: Alignment.center,
        decoration: BoxDecoration(color: Colors.red),
        child: Text(
          item,
          style: TextStyle(color: Colors.white, fontSize: 20),
        ),
      ),
    );
  }

  //顯示點擊事件
  static Widget getDialog(String item) {
    return new AlertDialog(
      title: new Text(
        //標題
        '提示',
        style: new TextStyle(color: Colors.red[300], fontSize: 18),
      ),
      content: new Text(item), //提示語
      actions: <Widget>[
        new FlatButton(
            //一個扁平的Material按鈕
            onPressed: () {
              Navigator.of(context1).pop(); //彈窗消失
            },
            child: Text('取消')),
        new FlatButton(
            //對話框按鈕
            onPressed: () {
              Navigator.of(context1).pop(); //彈窗消失
            },
            child: Text('確定')),
      ],
    );
  }

  Widget build(BuildContext context) {
    context1 = context;
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(
          '首頁',
          style: textStyle,
        ),
      ),
      body: new ListView(
        shrinkWrap: true,
        children: <Widget>[
          swiperSection,
          gridSection,//涉及listView嵌套GridView
        ],
      ),
    );
  }
}

 到此完成了,有更好的建議評論區見!

 

上一篇:flutter學習四:使用自定義字體 

下一篇:flutter學習六:實現http網絡請求

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