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网络请求

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值