2

说点儿闲话

大部分app都有轮播图,一般是展示一些新闻公告通知等图片,在flutter最强大的siwiper, 多种布局方式,无限轮播,Android和IOS双端适配,github:flutter_swiper

使用:

加载图片

一般是从本地代码中或者使用网络图片,那么,首先将资源添加到项目的 pubspec.yaml 文件中(更多细节请参阅Assets and images):

flutter:
   assets:
   - images/news_1.png
   - images/news_1.png
   - images/news_1.png

如果项目中所需要使用的图片资源太多,也可以直接直接这样写:
(1)、包含一个目录下的所有 assets,需要在目录名称的结尾加上/

flutter:
  assets:
    - assets/

注意只包含目录下根节点的所有文件。
(2)、如果要添加子目录下的文件,需要给每个目录创建节点:

flutter:
    assets: [images/,images/index-icons/] # 配置代码中使用的图片所放置的文件夹及其子文件夹
 

显示base64图片

这里插个题外话,使用图片显示的辑中方法:Image class: A widget that displays an image.
其中,Image.memory可以用来显示base64图片,具体使用如下:

import 'dart:convert';

//"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAAuCAYAAACvdRK..."
// 直接获取`base64,`之后的数据
pictureData = "iVBORw0KGgoAAAANSUhEUgAAAKAAAAAuCAYAAACvdRK..."
Image.memory(
    Base64Decoder().convert(pictureData), // 转成Uint8List
    fit: BoxFit.contain,
    height: 160,
)

参考:flutter 显示base64 图片

flutter_swiper

pubspec.yaml文件里添加

flutter\_swiper : ^lastest\_version

到项目根目录下的 pubspec.yaml ,并且根目录运行命令行

flutter packages get

flutter_swiper的最新版本号查看:pub.dev:flutter_swiper

实现轮播图 代码

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

class IndexScreen extends StatefulWidget {
  @override
  _SwiperViewState createState() => _SwiperViewState();
}

class _SwiperViewState extends State<IndexScreen> {
  // 声明一个list,存放image Widget
  List<Widget> imageList = List();

  @override
  void initState() {
    imageList
      ..add(Image.asset(
        'images/news_1.png',
        height: 200,
        fit: BoxFit.fitWidth, // 显示可能拉伸,可能裁剪,宽度充满
      ))
      ..add(Image.asset(
        'images/news_2.png',
        height: 200,
        fit: BoxFit.fitWidth,
      ))
      ..add(Image.asset(
        'images/news_3.png',
        height: 200,
        fit: BoxFit.fitWidth,
      ));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        leading: Builder(
          builder: (BuildContext context) {
            // APP的logo图
            return Image.asset('images/logo-header.png');
          },
        ),
        title: new Text(
          'APP
          style: TextStyle(fontSize: 18.0, height: 1.2, fontFamily: "Courier"),
        ),
        actions: <Widget>[
          new IconButton(
              icon: new Icon(Icons.message),
              onPressed: () {
                // 右上角的通知消息图标,点击进入消息列表
                Navigator.push(
                  context,
                  new MaterialPageRoute(
                      builder: (context) => new MessageScreen()),
                );
              }),
        ],
      ),
      body: Column(
        children: <Widget>[
          Container(
            width: MediaQuery.of(context).size.width,
            height: 200,
            child: new Swiper(
              itemBuilder: _swiperBuilder,
              itemCount: 3,
              itemWidth: MediaQuery.of(context).size.width,
              itemHeight: 200.0,
              loop: true,
              autoplay: true,
              pagination: null,
              control: null,
              viewportFraction: 1,
              scale: 1,
            ),
          ),
          Container(
            // padding: const EdgeInsets.fromLTRB(0, 10, 0, 5),
            width: MediaQuery.of(context).size.width,
            // height: MediaQuery.of(context).size.height,
            // 将上方的header、底部菜单和轮播图的高度减掉
            height: MediaQuery.of(context).size.height - 400,             
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly, //对齐方式:平均间隔
              children: [
              // 下方的其他页面布局
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _swiperBuilder(BuildContext context, int index) {
    return (imageList[index]);
  }
}

以上是使用静态资源加载图片来实现轮播图,实际项目中,基本都是后端接口返回的数据,这就涉及到另外的知识点, GitHub - dio: 发起网络请求, 参见我整理的dio的相关学习记录: Flutter 使用dio来发起网络请求以及Cookie管理
通过接口请求后端返回的数据后,对数据进行处理并通过setState来更新视图,代码:

    setState(() {
        // 处理返回数据
        var rtn = response.data['content'];
        rtn.forEach((f) {
          // print("image title:" + f["title"] + " imageUrl:" + f["imageUrl"]);
          imageList
            ..add(Image.network(
              f["imageUrl"],
              height: 200,
              fit: BoxFit.fitWidth, // 显示可能拉伸,可能裁剪,宽度充满
            ));
        });
        // print(imageList);
      });

遇到的问题

在首页上,通过底部导航菜单点击跳转到另一个页面后,再回到首页,轮播图会出现疯狂的切换图片轮播一段时间后停下来继续以正常速度轮播,具体问题参我的提问:Flutter flutter_swiper轮播图的问题
这个问题我已经解决了,解决办法描述在我的提问下我自己的回答里记录了,这里就不再赘述了,直接附上解决是修改的代码:
IndexScreen 的 class中增加以下代码:

  bool isLoading = true;  
  
   setState(() {
        // 处理返回数据 上文中有,省略了
        isLoading = false;
        // print(imageList);
   });
   
  
  Widget _buildProgressIndicator() {
    return new Padding(
      padding: const EdgeInsets.all(8.0),
      child: new Center(
        child: new Opacity(
          opacity: isLoading ? 1.0 : 00,
          child: new CircularProgressIndicator(),
        ),
      ),
    );
  }

build方法中增加判断:

  Container(
            width: MediaQuery.of(context).size.width,
            height: 125,
            child: imageList.length == 0
                ? _buildProgressIndicator()
                : new Swiper(
                    itemBuilder: _swiperBuilder,
                    itemCount: imageList.length,
                    itemWidth: MediaQuery.of(context).size.width,
                    itemHeight: 125.0,
                    loop: true,
                    autoplay: true,
                    autoplayDelay: 3000, //自动播放延迟
                    autoplayDisableOnInteraction: true, //触发时是否停止播放
                    pagination: null, //设置 new SwiperPagination() 展示默认分页指示器
                    control: null, //设置 new SwiperControl() 展示默认分页按钮
                    controller: swiperController,
                    viewportFraction: 1,
                    scale: 1,
                  ),
          ),
  

参考资料:

github:flutter_swiper
Assets and images
pub.dev:flutter_swiper
笔记-Flutter之轮播图(多样式)

Flutter 三种方式实现页面切换后保持原页面状态

相关文章

Flutter APP开发 学习记录: bottomNavigationBar底部导航菜单 本篇文章是底部导航菜单这篇文章中对应的IndexScreen()的布局

dio的相关学习记录: Flutter 使用dio来发起网络请求以及Cookie管理


北堂棣
6.6k 声望116 粉丝

2016年应届毕业生。