Flutter实现 瀑布流+高斯模糊效果+上拉加载+下拉刷新

1.心动我的

/// 我心动的列表
///
/// created by hujintao
/// created at 2019-09-11
//
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fpdxapp/components/dialogs/app_update.dart';
import 'package:fpdxapp/components/dialogs/dialog_wrapper.dart';
import 'package:fpdxapp/components/dialogs/unlock_cp_dialog.dart';
import 'package:fpdxapp/components/vip_tag.dart';
import 'package:fpdxapp/constants/icons.dart';
import 'package:fpdxapp/constants/style.dart';
import 'package:fpdxapp/dao/friends/heartBeat.dart';
import 'package:fpdxapp/model/friends/heartBeat.dart';
import 'package:fpdxapp/utils/date_util.dart';
import 'package:fpdxapp/utils/toast.dart';
import 'package:fpdxapp/utils/utils.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';

class MyHeartBeatList extends StatefulWidget {
  @override
  _MyHeartBeatListState createState() => _MyHeartBeatListState();
}

class _MyHeartBeatListState extends State<MyHeartBeatList> with AutomaticKeepAliveClientMixin{

  //加载更多key 必填
  GlobalKey<RefreshFooterState> _footerKey =
      new GlobalKey<RefreshFooterState>();

  //下拉刷新key 必填
  GlobalKey<RefreshHeaderState> _headerKey =
      new GlobalKey<RefreshHeaderState>();

  List<HeartBeatList> heartBeatList = [];
  int _page;
  ScrollController _scrollController;

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;
  /// 渐变色
  final gradient = Utils.parseAngleToAlignment(90);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._refreshData();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: this.heartBeatList != null && this.heartBeatList.length > 0
          ? _buildContent()
          : _noDataWidget(),
    );
  }

  Widget _buildContent() {
    return EasyRefresh(
      refreshHeader: ClassicsHeader(
        key: _headerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        refreshReadyText: '下拉刷新',
        refreshingText: '正在努力刷新',
        refreshedText: '加载完成',
        showMore: true,
        moreInfo: '正在加载中',
      ),
      refreshFooter: ClassicsFooter(
        key: _footerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        showMore: true,
        noMoreText: '暂时没有更多了',
        loadReadyText: '上拉加载',
        loadedText: '加载完毕',
        loadText: '上拉加载更多',
        loadingText: '正在努力加载更多',
        moreInfo: '正在加载中',
      ),
      child: new StaggeredGridView.countBuilder(
        itemCount:
            this.heartBeatList.length > 0 ? this.heartBeatList.length : 0,
        primary: false,
        crossAxisCount: 4,
        mainAxisSpacing: ScreenUtil().setWidth(30),
        crossAxisSpacing: ScreenUtil().setWidth(30),
        itemBuilder: (BuildContext context, int index) => new Container(
          height: ScreenUtil().setHeight(582),
            color: Colors.transparent,
            child: _buildImageItem(heartBeatList[index])),
        staggeredTileBuilder: (int index) =>
            new StaggeredTile.count(2, index.isEven ? 3 : 2.5),
        padding: EdgeInsets.only(
            left: ScreenUtil().setWidth(32), right: ScreenUtil().setWidth(32)),
      ),
      loadMore: () async {
        print('没有更多了.......');
        _addMoreData();
      },
      onRefresh: () async {
        print('下拉刷新~~~~');
        _refreshData();
      },
    );
  }

  /// DetailItem
  Widget _buildImageItem(HeartBeatList item) {
    return new GestureDetector(
      onTap: () {
        Toast.show("点击了");
      },
      child: Container(
        decoration: BoxDecoration(
            color: Color(0xffF3F4F5),
            borderRadius: BorderRadius.circular(10.0),
            image: DecorationImage(
                image: NetworkImage(
                    item != null && item.photoSrc != null ? item.photoSrc : ''),
                fit: BoxFit.cover) //设置图片的填充模式
            ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            // 顶部阴影
            Container(
              height: ScreenUtil().setHeight(129),
              decoration: BoxDecoration(
                gradient: LinearGradient(
                    colors: [
                      Color(0xFF030303).withOpacity(0.06),
                      Color(0xFF565656).withOpacity(0.06),
                    ],
                    begin: Alignment(gradient['beginX'], gradient['beginY']),
                    end: Alignment(gradient['endX'], gradient['endY'])),
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10.0),
                  topRight: Radius.circular(10.0),
                ),
              ),
              child: Container(
                margin: EdgeInsets.only(
                  left: ScreenUtil().setWidth(10),
                  right: ScreenUtil().setWidth(17),
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.only(top: ScreenUtil().setHeight(17)),
                      child: Row(
                        children: <Widget>[
                          Icon(
                            MyIcons.heart,
                            size: ScreenUtil().setSp(40),
                            color: Colors.white,
                          ),
                          Container(
                            margin: EdgeInsets.only(
                              left: ScreenUtil().setWidth(5),
                              top: ScreenUtil().setWidth(5),
                            ),
                            child: Text(
                              item != null && item.praises != null
                                  ? item.praises.toString()
                                  : '',
                              style: TextStyle(
                                fontSize: ScreenUtil().setSp(20),
                                color: Colors.white,
                              ),
                              textAlign: TextAlign.center,
                            ),
                          )
                        ],
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.only(top: ScreenUtil().setHeight(19)),
                      child: ClipOval(
                        child: Container(
                          color: Colors.black.withOpacity(0.24),
                          padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
                          child: Icon(
                            MyIcons.lock,
                            size: ScreenUtil().setSp(42),
                            color: Colors.white,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            // 底部阴影
            Container(
              height: ScreenUtil().setHeight(129),
              decoration: BoxDecoration(
                gradient: LinearGradient(
                    colors: [
                      Color(0xFF030303).withOpacity(0.06),
                      Color(0xFF565656).withOpacity(0.06),
                    ],
                    begin: Alignment(gradient['beginX'], gradient['beginY']),
                    end: Alignment(gradient['endX'], gradient['endY'])),
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(10.0),
                  bottomRight: Radius.circular(10.0),
                ),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  // 标签
                  Container(
                    margin: EdgeInsets.only(top: ScreenUtil().setHeight(33)),
                    child: Row(
                      children: <Widget>[
                        // 性别标识
                        item.sex == 1
                            ? Container(
                                margin: EdgeInsets.only(
                                    left: ScreenUtil().setHeight(22)),
                                child: ClipOval(
                                  child: Container(
                                    color: Color(0xff6CC1FD),
                                    padding: EdgeInsets.all(
                                        ScreenUtil().setWidth(3)),
                                    child: Icon(
                                      MyIcons.sex_boy,
                                      size: ScreenUtil().setSp(20),
                                      color: Colors.white,
                                    ),
                                  ),
                                ),
                              )
                            : Container(
                                margin: EdgeInsets.only(
                                    left: ScreenUtil().setHeight(22)),
                                child: ClipOval(
                                  child: Container(
                                    color: MyColors.primary,
                                    padding: EdgeInsets.all(
                                        ScreenUtil().setWidth(3)),
                                    child: Icon(
                                      MyIcons.sex_girl,
                                      size: ScreenUtil().setSp(20),
                                      color: Colors.white,
                                    ),
                                  ),
                                ),
                              ),
                        // 认证标识
                        item.user.wxAuth != null && item.user.wxAuth != 0
                            ? Container(
                                margin: EdgeInsets.only(
                                    left: ScreenUtil().setHeight(9)),
                                child: Image(
                                  image: NetworkImage(
                                      'https://oss.pocketuniversity.cn/media/2019-01-05/5c3029ad417ce.png'),
                                  width: ScreenUtil().setWidth(25),
                                ),
                              )
                            : Container(),
                        SizedBox(
                          width: ScreenUtil().setWidth(5),
                        ),
                        // VIP标识
                        VipTag(item.user?.beVipAt ?? 0,
                            item.user?.supvipEndat ?? 0, 0)
                      ],
                    ),
                  ),
                  // 描述
                  Container(
                    margin: EdgeInsets.only(
                        left: ScreenUtil().setWidth(21),
                        right: ScreenUtil().setWidth(21)),
                    child: Text(
                      item.updatedAt != null
                          ? DateUtil.howLongAgo(item.updatedAt) + '心动过你'
                          : '',
                      overflow: TextOverflow.ellipsis,
                      maxLines: 1,
                      textAlign: TextAlign.left,
                      style: TextStyle(
                        fontSize: ScreenUtil().setSp(31),
                        color: Colors.white,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 无数据占位
  Widget _noDataWidget() {
    return Container(
      child: Center(
        child: Column(
          children: <Widget>[
            // 图片
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(199),
              ),
              child: Image(
                image: Utils.getAssetImgWithPath('nodata_heartBeatMine'),
                width: ScreenUtil().setWidth(451),
                height: ScreenUtil().setHeight(357),
                fit: BoxFit.cover,
              ),
            ),
            // 文字
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(29),
              ),
              child: Text(
                '你目前还没有心动的人~',
                style: TextStyle(
                    color: Color(0xFF999999), fontSize: ScreenUtil().setSp(30)),
              ),
            ),
            // 按钮
            GestureDetector(
              onTap: () {
                Toast.show('去首页心动');
              },
              child: Container(
                margin: EdgeInsets.only(
                  top: ScreenUtil().setHeight(70),
                ),
                width: ScreenUtil().setWidth(520),
                height: ScreenUtil().setHeight(100),
                decoration: BoxDecoration(
                  color: Color(0xffFFF1F2),
                  // 设置渐变色
                  gradient: LinearGradient(
                    colors: [Color(0xFFFFF9FB1), Color(0xFFFF69A2)],
                    begin: Alignment(-1, -1),
                    end: Alignment(1.0, 0.56),
                  ),
                  borderRadius:
                      BorderRadius.circular(ScreenUtil().setHeight(50)),
                ),
                child: Center(
                  child: Text(
                    '去首页心动',
                    style: TextStyle(
                        color: Colors.white, fontSize: ScreenUtil().setSp(35)),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 下拉刷新数据
  Future<Null> _refreshData() async {
    _page = 0;
    _getPostData(false);
  }

  /// 上拉加载数据
  Future<Null> _addMoreData() async {
    _page++;
    _getPostData(true);
  }

  /// 获取我心动的列表数据
  void _getPostData(bool _beAdd) async {
    print('page:${_page}');
    var r = await HeartBeatDao.getMyHeartBeatAllList(page: _page);
    setState(() {
      if (!_beAdd) {
        heartBeatList.clear();
        heartBeatList = r.data;
      } else {
        heartBeatList.addAll(r.data);
      }
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _scrollController = ScrollController();

    _scrollController.addListener(_handleScroll);
  }

  void _handleScroll() {}

  @override
  void dispose() {
    _scrollController?.removeListener(_handleScroll);
    super.dispose();
  }
}

2.我心动的列表

import 'dart:ui';

/// 心动我的列表
///
/// created by hujintao
/// created at 2019-09-11
//
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:fpdxapp/components/blur_widget/blur_widget.dart';
import 'package:fpdxapp/components/vip_tag.dart';
import 'package:fpdxapp/constants/icons.dart';
import 'package:fpdxapp/constants/style.dart';
import 'package:fpdxapp/dao/friends/heartBeat.dart';
import 'package:fpdxapp/model/friends/heartBeat.dart';
import 'package:fpdxapp/utils/date_util.dart';
import 'package:fpdxapp/utils/toast.dart';
import 'package:fpdxapp/utils/utils.dart';

class HeartBeatMineList extends StatefulWidget {
  @override
  _HeartBeatMineListState createState() => _HeartBeatMineListState();
}

class _HeartBeatMineListState extends State<HeartBeatMineList>
    with AutomaticKeepAliveClientMixin {
  //加载更多key 必填
  GlobalKey<RefreshFooterState> _footerKey =
      new GlobalKey<RefreshFooterState>();

  //下拉刷新key 必填
  GlobalKey<RefreshHeaderState> _headerKey =
      new GlobalKey<RefreshHeaderState>();

  List<HeartBeatList> heartBeatList = [];
  int _page;

  ScrollController _scrollController;

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  /// 渐变色
  final gradient = Utils.parseAngleToAlignment(90);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._refreshData();
  }

  /// 下拉刷新数据
  Future<Null> _refreshData() async {
    _page = 0;
    _getPostData(false);
  }

  /// 上拉加载数据
  Future<Null> _addMoreData() async {
    _page++;
    _getPostData(true);
  }

  /// 获取我心动的列表数据
  void _getPostData(bool _beAdd) async {
    print('page:${_page}');
    var r = await HeartBeatDao.getHeartBeatMineAllList(page: _page);
    setState(() {
      if (!_beAdd) {
        heartBeatList.clear();
        heartBeatList = r.data;
      } else {
        heartBeatList.addAll(r.data);
      }
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _scrollController = ScrollController();

    _scrollController.addListener(_handleScroll);
  }

  void _handleScroll() {}

  @override
  void dispose() {
    _scrollController?.removeListener(_handleScroll);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: this.heartBeatList != null && this.heartBeatList.length > 0
          ? _buildContent()
          : _noDataWidget(),
    );
  }

  Widget _buildContent() {
    return EasyRefresh(
      refreshHeader: ClassicsHeader(
        key: _headerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        refreshReadyText: '下拉刷新',
        refreshingText: '正在努力刷新',
        refreshedText: '加载完成',
        showMore: true,
        moreInfo: '正在加载中',
      ),
      refreshFooter: ClassicsFooter(
        key: _footerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        showMore: true,
        noMoreText: '暂时没有更多了',
        loadReadyText: '上拉加载',
        loadedText: '加载完毕',
        loadText: '上拉加载更多',
        loadingText: '正在努力加载更多',
        moreInfo: '正在加载中',
      ),
      child: new StaggeredGridView.countBuilder(
        itemCount:
            this.heartBeatList.length > 0 ? this.heartBeatList.length : 0,
        primary: false,
        crossAxisCount: 4,
        mainAxisSpacing: ScreenUtil().setWidth(30),
        crossAxisSpacing: ScreenUtil().setWidth(30),
        itemBuilder: (BuildContext context, int index) => new Container(
            color: Colors.transparent,
            child: _buildImageItem(heartBeatList[index])),
        staggeredTileBuilder: (int index) =>
            new StaggeredTile.count(2, index.isEven ? 3 : 2.5),
        padding: EdgeInsets.only(
            left: ScreenUtil().setWidth(32), right: ScreenUtil().setWidth(32)),
      ),
      loadMore: () async {
        print('没有更多了.......');
        _addMoreData();
      },
      onRefresh: () async {
        print('下拉刷新~~~~');
        _refreshData();
      },
    );
  }

  /// DetailItem
  Widget _buildImageItem(HeartBeatList item) {
    return new GestureDetector(
      onTap: () {
        Toast.show("点击了");
      },
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [
            BoxShadow(
                color: Color(0xffF3F4F5), offset: Offset(1, 1), spreadRadius: 1)
          ],
          borderRadius: BorderRadius.only(
            bottomLeft: Radius.circular(10.0),
            bottomRight: Radius.circular(10.0),
          ),
        ),
        child: Stack(
          overflow: Overflow.clip,
          alignment: Alignment(-1, 1),
          children: <Widget>[
            // 背景图片
            Container(
              decoration: BoxDecoration(
                  color: Color(0xffF3F4F5),
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(10.0),
                    topRight: Radius.circular(10.0),
                  ),
                  image: DecorationImage(
                      image: NetworkImage(item != null && item.photoSrc != null
                          ? item.photoSrc
                          : ''),
                      fit: BoxFit.cover) //设置图片的填充模式
                  ),
              margin: EdgeInsets.only(bottom: ScreenUtil().setHeight(20)),
            ),
            // 矩形高斯模糊效果
            BlurRectWidget(
              child: Container(),
              opacity: 0.8,
            ),
            // 主题
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              bottom: ScreenUtil().setHeight(20),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  // 顶部阴影
                  Container(
                    height: ScreenUtil().setHeight(129),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                          colors: [
                            Color(0xFF030303).withOpacity(0.06),
                            Color(0xFF565656).withOpacity(0.06),
                          ],
                          begin:
                              Alignment(gradient['beginX'], gradient['beginY']),
                          end: Alignment(gradient['endX'], gradient['endY'])),
                      borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(10.0),
                        topRight: Radius.circular(10.0),
                      ),
                    ),
                    child: Container(
                      margin: EdgeInsets.only(
                        left: ScreenUtil().setWidth(10),
                        right: ScreenUtil().setWidth(17),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Container(
                            margin: EdgeInsets.only(
                                top: ScreenUtil().setHeight(17)),
                            child: Row(
                              children: <Widget>[
                                Icon(
                                  MyIcons.heart,
                                  size: ScreenUtil().setSp(40),
                                  color: Colors.white,
                                ),
                                Container(
                                  margin: EdgeInsets.only(
                                    left: ScreenUtil().setWidth(5),
                                    top: ScreenUtil().setWidth(5),
                                  ),
                                  child: Text(
                                    item != null && item.praises != null
                                        ? item.praises.toString()
                                        : '',
                                    style: TextStyle(
                                      fontSize: ScreenUtil().setSp(20),
                                      color: Colors.white,
                                    ),
                                    textAlign: TextAlign.center,
                                  ),
                                )
                              ],
                            ),
                          ),
                          Container(
                            margin: EdgeInsets.only(
                                top: ScreenUtil().setHeight(19)),
                            child: ClipOval(
                              child: Container(
                                color: Colors.black.withOpacity(0.24),
                                padding:
                                    EdgeInsets.all(ScreenUtil().setWidth(10)),
                                child: Icon(
                                  MyIcons.lock,
                                  size: ScreenUtil().setSp(42),
                                  color: Colors.white,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  // 底部阴影
                  Container(
                    height: ScreenUtil().setHeight(129),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                          colors: [
                            Color(0xFF030303).withOpacity(0.06),
                            Color(0xFF565656).withOpacity(0.06),
                          ],
                          begin:
                              Alignment(gradient['beginX'], gradient['beginY']),
                          end: Alignment(gradient['endX'], gradient['endY'])),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        // 标签
                        Container(
                          margin:
                              EdgeInsets.only(top: ScreenUtil().setHeight(33)),
                          child: Row(
                            children: <Widget>[
                              // 性别标识
                              item.sex == 1
                                  ? Container(
                                      margin: EdgeInsets.only(
                                          left: ScreenUtil().setHeight(22)),
                                      child: ClipOval(
                                        child: Container(
                                          color: Color(0xff6CC1FD),
                                          padding: EdgeInsets.all(
                                              ScreenUtil().setWidth(3)),
                                          child: Icon(
                                            MyIcons.sex_boy,
                                            size: ScreenUtil().setSp(20),
                                            color: Colors.white,
                                          ),
                                        ),
                                      ),
                                    )
                                  : Container(
                                      margin: EdgeInsets.only(
                                          left: ScreenUtil().setHeight(22)),
                                      child: ClipOval(
                                        child: Container(
                                          color: MyColors.primary,
                                          padding: EdgeInsets.all(
                                              ScreenUtil().setWidth(3)),
                                          child: Icon(
                                            MyIcons.sex_girl,
                                            size: ScreenUtil().setSp(20),
                                            color: Colors.white,
                                          ),
                                        ),
                                      ),
                                    ),
                              // 认证标识
                              item.user.wxAuth != null && item.user.wxAuth != 0
                                  ? Container(
                                      margin: EdgeInsets.only(
                                          left: ScreenUtil().setHeight(9)),
                                      child: Image(
                                        image: NetworkImage(
                                            'https://oss.pocketuniversity.cn/media/2019-01-05/5c3029ad417ce.png'),
                                        width: ScreenUtil().setWidth(25),
                                      ),
                                    )
                                  : Container(),
                              SizedBox(
                                width: ScreenUtil().setWidth(5),
                              ),
                              // VIP标识
                              VipTag(item.user?.beVipAt ?? 0,
                                  item.user?.supvipEndat ?? 0, 0)
                            ],
                          ),
                        ),
                        // 描述
                        Container(
                          margin: EdgeInsets.only(
                              left: ScreenUtil().setWidth(21),
                              right: ScreenUtil().setWidth(21)),
                          child: Text(
                            item.updatedAt != null
                                ? DateUtil.howLongAgo(item.updatedAt) + '心动过你'
                                : '',
                            overflow: TextOverflow.ellipsis,
                            maxLines: 1,
                            textAlign: TextAlign.left,
                            style: TextStyle(
                              fontSize: ScreenUtil().setSp(31),
                              color: Colors.white,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            // 进度条
            Container(
              height: ScreenUtil().setHeight(20),
              child: _ProgressBar(
                start: 0,
                end: 0,
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 无数据占位
  Widget _noDataWidget() {
    return Container(
      child: Center(
        child: Column(
          children: <Widget>[
            // 图片
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(199),
              ),
              child: Image(
                image: Utils.getAssetImgWithPath('nodata_myHeartBeat'),
                width: ScreenUtil().setWidth(451),
                height: ScreenUtil().setHeight(357),
                fit: BoxFit.cover,
              ),
            ),
            // 文字
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(29),
              ),
              child: Text(
                '你目前还没有心动的人~',
                style: TextStyle(
                    color: Color(0xFF999999), fontSize: ScreenUtil().setSp(30)),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 创建交友卡片 占位
  Widget _noIDCardWidget() {
    return Container(
      child: Center(
        child: Column(
          children: <Widget>[
            // 图片
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(199),
              ),
              child: Image(
                image: Utils.getAssetImgWithPath('nodata_heartBeatMine_noID'),
                width: ScreenUtil().setWidth(451),
                height: ScreenUtil().setHeight(357),
                fit: BoxFit.cover,
              ),
            ),
            // 文字
            Container(
              margin: EdgeInsets.only(
                top: ScreenUtil().setHeight(29),
              ),
              child: Text(
                '创建交友卡片后,可解锁“心动我的”人',
                style: TextStyle(
                    color: Color(0xFF999999), fontSize: ScreenUtil().setSp(30)),
              ),
            ),
            // 按钮
            GestureDetector(
              onTap: () {
                Toast.show('创建交友卡片');
              },
              child: Container(
                margin: EdgeInsets.only(
                  top: ScreenUtil().setHeight(70),
                ),
                width: ScreenUtil().setWidth(520),
                height: ScreenUtil().setHeight(100),
                decoration: BoxDecoration(
                  color: Color(0xffFFF1F2),
                  // 设置渐变色
                  gradient: LinearGradient(
                    colors: [Color(0xFFFFF9FB1), Color(0xFFFF69A2)],
                    begin: Alignment(-1, -1),
                    end: Alignment(1.0, 0.56),
                  ),
                  borderRadius:
                      BorderRadius.circular(ScreenUtil().setHeight(50)),
                ),
                child: Center(
                  child: Text(
                    '创建交友卡片',
                    style: TextStyle(
                        color: Colors.white, fontSize: ScreenUtil().setSp(35)),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

}

/// 进度条
class _ProgressBar extends StatelessWidget {

  /// 起始进度, <1
  final double start;

  /// 结束进度, <=1
  final double end;

  _ProgressBar({this.start, this.end});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: Future.delayed(const Duration(milliseconds: 300)),
        builder: (_, data) => AnimatedContainer(
              height: ScreenUtil().setHeight(6),
              width: MediaQuery.of(context).size.width * this.end,
              duration: Duration(milliseconds: 300),
              decoration: BoxDecoration(
                color: MyColors.primary,
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(10.0),
                  bottomRight: Radius.circular(10.0),
                ),
              ),
            ));
  }
}

效果图

瀑布流-效果图.gif

补充

1.瀑布流关键代码

Widget _buildContent() {
    return EasyRefresh(
      refreshHeader: ClassicsHeader(
        key: _headerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        refreshReadyText: '下拉刷新',
        refreshingText: '正在努力刷新',
        refreshedText: '加载完成',
        showMore: true,
        moreInfo: '正在加载中',
      ),
      refreshFooter: ClassicsFooter(
        key: _footerKey,
        bgColor: Colors.white,
        textColor: Colors.pink,
        moreInfoColor: Colors.pink,
        showMore: true,
        noMoreText: '暂时没有更多了',
        loadReadyText: '上拉加载',
        loadedText: '加载完毕',
        loadText: '上拉加载更多',
        loadingText: '正在努力加载更多',
        moreInfo: '正在加载中',
      ),
      child: new StaggeredGridView.countBuilder(
        itemCount:
            this.heartBeatList.length > 0 ? this.heartBeatList.length : 0,
        primary: false,
        crossAxisCount: 4,
        mainAxisSpacing: ScreenUtil().setWidth(30),
        crossAxisSpacing: ScreenUtil().setWidth(30),
        itemBuilder: (BuildContext context, int index) => new Container(
          height: ScreenUtil().setHeight(582),
            color: Colors.transparent,
            child: _buildImageItem(heartBeatList[index])),
        staggeredTileBuilder: (int index) =>
            new StaggeredTile.count(2, index.isEven ? 3 : 2.5),
        padding: EdgeInsets.only(
            left: ScreenUtil().setWidth(32), right: ScreenUtil().setWidth(32)),
      ),
      loadMore: () async {
        print('没有更多了.......');
        _addMoreData();
      },
      onRefresh: () async {
        print('下拉刷新~~~~');
        _refreshData();
      },
    );
  }

2.高斯模糊效果

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

/// 矩形高斯模糊效果
class BlurRectWidget extends StatefulWidget {

  final Widget child;

  /// 模糊值
  final double sigmaX;
  final double sigmaY;

  /// 透明度
  final double opacity;

  /// 外边距
  final double blurMargin;


  const BlurRectWidget(
      {Key key,
      this.child,
      this.sigmaX,
      this.sigmaY,
      this.opacity,
      this.blurMargin})
      : super(key: key);

  @override
  _BlurRectWidgetState createState() => _BlurRectWidgetState();
}

class _BlurRectWidgetState extends State<BlurRectWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: widget.blurMargin != null
          ? widget.blurMargin
          : EdgeInsets.only(bottom: ScreenUtil().setHeight(20)),
      child: ClipRRect(
        borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
        child: BackdropFilter(
          filter: ImageFilter.blur(
            sigmaX: this.widget.sigmaX != null ? this.widget.sigmaX : 20,
            sigmaY: this.widget.sigmaY != null ? this.widget.sigmaY : 20,
          ),
          child: Container(
            color: Colors.white10,
            child: this.widget.opacity != null
                ? Opacity(
                    opacity: widget.opacity,
                    child: this.widget.child,
                  )
                : this.widget.child,
          ),
        ),
      ),
    );
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容

  • 一.Hello Filter 1.编写FirstFilter 2.配置web.xml 二.中文处理 三.登陆验证
    ticktackdong阅读 265评论 0 0
  • 生活中我们会遇到困难,这时我们需要去求助别人。但是一旦困难很巨大,那么我们就去请求别人,那么很有可能会被拒绝...
    young后知后觉阅读 2,143评论 0 1
  • “那我们去学校外面吃点东西吧。”江小米的声音里没有了刚刚的小愤怒,变成了平时的样子。 “好,那我知道附近有个好吃的...
    侯小白阅读 234评论 1 0