Flutter 中恨不得直接贴来的布局效果

773 阅读3分钟

家长里短

隔一段时间,自己总会有点新奇的想法,在编码的过程中,到底要积累多少内容,或者说踩过多少坑,才能“顺风顺水”,如果你没有读过洋小洋其他文章的话,那还是先说一,来了就不许走了。其实我也不是个专业的写手,但是我知道有很多人在一起共同的学习,可能以后会像掘金大佬一样,一篇一出就是几万字,剖析原理,那这些,咱慢慢来,之后我没准也写个什么5万字React.js终于开源了,也有老哥老妹看不过瘾,说是太短了,不过chixu没得事儿,咱们持续的,持久的更新,做个持久Boy -- Do it

  • 主题:自己研究Flutter 部件,手撸常见的布局效果
  • 更新频次:持续、一直、always

进入正题

首先先来看一下效果,这也是笔者踩了些坑才写出如此简陋的效果,那至于踩了什么坑还是建议看一下,这个 Flutter实际项目开发中踩坑大合集(持续更新..)

效果

QGFSbR.gif
此时正在看着的你,该说了这不简单吗,一个滚动的部件,搞定

  • SingleChildScrollView
SingleChildScrollView({
 this.scrollDirection = Axis.vertical, //滚动方向,默认是垂直方向
 this.reverse = false, 
 this.padding, 
 bool primary, 
 this.physics, 
 this.controller,
 this.child,
})
  • ListView

ListView({
  ...  
  //可滚动widget公共参数
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  bool primary,
  ScrollPhysics physics,
  EdgeInsetsGeometry padding,

  //ListView各个构造函数的共同参数  
  double itemExtent,
  bool shrinkWrap = false,
  bool addAutomaticKeepAlives = true,
  bool addRepaintBoundaries = true,
  double cacheExtent,

  //子widget列表
  List<Widget> children = const <Widget>[],
})
  • GridView

GridView({
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  bool primary,
  ScrollPhysics physics,
  bool shrinkWrap = false,
  EdgeInsetsGeometry padding,
  @required SliverGridDelegate gridDelegate, //控制子widget layout的委托
  bool addAutomaticKeepAlives = true,
  bool addRepaintBoundaries = true,
  double cacheExtent,
  List<Widget> children = const <Widget>[],
})

这不是那么多滚动的部件呢吗?可是咱们要看下数据

final List listData = [
  {
    "date": "2019-12-05",
    "list": [
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      }
    ]
  },
  {
    "date": "2019-12-04",
    "list": [
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      }
    ]
  },
];

也就是说这个数据是不确定的,所以呢咱们就来用一下大名鼎鼎的Sliver 这个东西很厉害的,能做出一些很炫酷的滚动动画,首先不太明白的,咱们可以看文末是有一篇文章讲解,我认为蛮好

引包

常规操作,莫怪

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';

主要咱们有用到图片的缓存所以就使用到第二个cached_network_image

搞数据

final List listData = [
  {
    "date": "2019-12-05",
    "list": [
      {
        "pictureURL": "https://yayxs.github.io/head.jpg",
      },
    ]
  },
  ....................
];

这里咱们上边有看过

声明controller

ScrollController _controller = new ScrollController();

这个还是很有必要的,因为我们要有个统一化的滚动效果 为了避免内存泄露,需要调用_controller.dispose

 @override
  void dispose() {
    //为了避免内存泄露,需要调用_controller.dispose
    _controller.dispose();
    super.dispose();
  }

核心代码


Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: <Widget>[
        SliverList(
            delegate: SliverChildBuilderDelegate(
          (context, index) => Container(
            child: Container(
              child: Column(
                children: <Widget>[
                  _dateTitle(listData[index]['date']),
                  Container(
                      decoration: BoxDecoration(
                          border: Border.all(width: 1, color: Colors.red)),
                      child: Wrap(
                          spacing: 8.0, // 主轴(水平)方向间距
                          runSpacing: 4.0, // 纵轴(垂直)方向间距
                          alignment: WrapAlignment.spaceEvenly, //沿主轴方向居中
                          children: (listData[index]['list'])
                              .map<Widget>((item) => Container(
                                    child: _onePic(item['pictureURL']),
                                  ))
                              .toList())),
                ],
              ),
            ),
          ),
          childCount: listData.length,
        ))
      ],
    );
  }

 // 日期
  Widget _dateTitle(String date) {
    return Container(
      child: Padding(
        padding: EdgeInsets.symmetric(vertical: 16),
        child: Text(
          date,
          textAlign: TextAlign.center,
          style: TextStyle(fontSize: 20),
        ),
      ),
    );
  }
  // 每张图片
  Widget _onePic(url) {
    return Container(
      width: 200,
      height: 200,
      padding: EdgeInsets.all(5),
      child: CachedNetworkImage(
        imageUrl: url,
        fit: BoxFit.cover,
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) => Icon(Icons.error),
      ),
    );
  }

那先这样简明扼要的聊一下,详细代码可以见滚动效果 已经有辣么多Demo 了

QGAobd.png

友情链接

  • Flutter Packages 第三方包把玩Demos聚合地 就链接这一个吧,一个主题是使用第三方的包,一个是自己手写项目中常见的效果。同时也欢迎你来到我的github 转转,有个小项目在更新呦,是这个,截止目前已经8 颗星了,开森---

鸣谢

在Flutter中创建有意思的滚动效果 - Sliver系列 #18


-- End but thank you --