Flutter占位视图 2022-11-08 周二

简介

一般表格的列表会提供一个空视图。然后在拉网络数据的时候,给一个loading表示数据传输状态。
在loading的时候,放空视图不是很好。但是又没有数据,所以很多时候会是空白视图,加一个loading。
这个过渡状态有时候1秒不到,有时候两三秒,也有时候七八秒,这个要看网络数据访问的状态。

图片加载过程会有一个占位图,那么网络访问的时候,就给整个页面给个占位页面。
并且这个时候在进行网络访问,所以一般会给个动画,表示在努力加载数据。

搜索插件

在pub.dev输入关键shimmer,发现有一个插件特别受欢迎。

企业微信截图_4fc94622-b3ea-4fdc-b352-57000929a1ab.png

这种优势很明显,不是特殊情况的话,就用这个就好了。

安装插件

flutter pub add shimmer

封装

占位图不能做到前端一样分步加载,只能重新写一个视图。
占位图大多数时候是一个矩形,少部分是一个圆形,所以可以封装成一个组件。
颜色的话用不同透明度的灰色比较好。

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

class ShimmerWidget extends StatelessWidget {
  final double width;
  final double height;
  final ShapeBorder shapeBorder;
  final Color baseColor;
  final Color highlightColor;

  const ShimmerWidget({
    Key? key,
    required this.width,
    required this.height,
    this.shapeBorder = const RoundedRectangleBorder(),
    this.baseColor = const Color(0x80000000),
    this.highlightColor = const Color(0x33000000),
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Shimmer.fromColors(
      baseColor: baseColor,
      highlightColor: highlightColor,
      child: Container(
        width: width,
        height: height,
        decoration: ShapeDecoration(
          color: const Color(0x4D000000),
          shape: shapeBorder,
        ),
      ),
    );
  }
}

使用

可以把这个自定义的ShimmerWidget组件当做SizedBox来使用。按照设计图给尺寸就行。

/// 闪烁视图
  Widget _buildShimmer() {
    return Container(
      margin: EdgeInsets.symmetric(
        horizontal: 10.w,
      ),
      child: ListView.builder(
        itemCount: 5,
        itemBuilder: (context, index) {
          return Container(
            margin: EdgeInsets.only(
              top: 10.h,
            ),
            padding: EdgeInsets.symmetric(
              horizontal: 10.w,
              vertical: 15.h,
            ),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(6.r),
              boxShadow: const [
                BoxShadow(
                  color: Color(0x0D000000),
                  offset: Offset(0.0, 1.0),
                  blurRadius: 5,
                ),
              ],
            ),
            child: Column(
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Row(
                      children: [
                        ShimmerWidget(
                          width: 16.w,
                          height: 16.w,
                        ),
                        SizedBox(
                          width: 5.w,
                        ),
                        ShimmerWidget(
                          width: 200.w,
                          height: 16.h,
                        ),
                      ],
                    ),
                    ShimmerWidget(
                      width: 80.w,
                      height: 16.h,
                    ),
                  ],
                ),
                SizedBox(
                  height: 10.h,
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    ShimmerWidget(
                      width: 80.w,
                      height: 80.w,
                    ),
                    SizedBox(
                      width: 5.w,
                    ),
                    Expanded(
                      child: Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              ShimmerWidget(
                                width: 180.w,
                                height: 16.h,
                              ),
                              ShimmerWidget(
                                width: 60.w,
                                height: 16.h,
                              ),
                            ],
                          ),
                          SizedBox(
                            height: 5.h,
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              ShimmerWidget(
                                width: 180.w,
                                height: 16.h,
                              ),
                              ShimmerWidget(
                                width: 12.w,
                                height: 16.h,
                              ),
                            ],
                          ),
                          SizedBox(
                            height: 5.h,
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              ShimmerWidget(
                                width: 100.w,
                                height: 16.h,
                              ),
                              ShimmerWidget(
                                width: 70.w,
                                height: 16.h,
                              ),
                            ],
                          ),
                          SizedBox(
                            height: 5.h,
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              ShimmerWidget(
                                width: 80.w,
                                height: 16.h,
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 5.h,
                ),
                const Divider(
                  color: Color(0xFFF2F2F2),
                  thickness: 0.5,
                ),
                SizedBox(
                  height: 10.h,
                ),
                ShimmerWidget(
                  width: double.infinity,
                  height: 20.h,
                ),
              ],
            ),
          );
        },
      ),
    );
  }

效果

shimmer.png

参考文章

Flutter 中的 Shimmer 动画效果

你可能感兴趣的:(Flutter占位视图 2022-11-08 周二)