iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
1
Mobile Development

新手試試用Flutter做Netflix UI系列 第 23

[Day23]Flutter Netflix UI 使用Shimmer為首頁加個微光閃爍的載入畫面

  • 分享至 

  • xImage
  •  

大家好,今天我們還是想辦法來做一些載入時候的效果,今天我們使用的是Shimmer
這是一個package,顯示的效果是微光閃過的感覺。

跟前面幾篇一樣我們使用一個FutureBuilder來做個異步任務,如果已經載入數據則顯示畫面,否則是一個Loading的Shimmer動畫

  Future _getData() {
    return Future.delayed(Duration(seconds: 2), () {});
  }

   FutureBuilder(
            future: _getData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return SliverList(
                    delegate: SliverChildListDelegate([
                  MajorRecommendedVideo(),
                  WonderfulPreview(),
                  RecommendedMenu(_series1),
                  RecommendedMenu(_series2),
                  Top10List(),
                  SizedBox(
                    height: 30.0,
                  )
                ]));
              }

              return _buildLoading();
            })

Shimmer

先在pubspec.yaml檔裡面新增

  shimmer: 1.1.1

官方示例可以看到使用這個shimmer時把它套在某個widget外,就可以有動畫效果

SizedBox(
  width: 200.0,
  height: 100.0,
  child: Shimmer.fromColors(
    baseColor: Colors.red,
    highlightColor: Colors.yellow,
    child: Text(
      'Shimmer',
      textAlign: TextAlign.center,
      style: TextStyle(
        fontSize: 40.0,
        fontWeight:
        FontWeight.bold,
      ),
    ),
  ),
);

我們可以控制的有顏色、方向、時間、次數等

Shimmer.fromColors({
    Key key,
    @required this.child,
    @required Color baseColor,
    @required Color highlightColor,
    this.period = const Duration(milliseconds: 1500),
    this.direction = ShimmerDirection.ltr,
    this.loop = 0,
    this.enabled = true,
  })

如下,我把載入的顯示的畫面用Container、Column、CircleAvatar、ListView構建起來,並且用Shimmer將他們都包起來,整體呈現效果

  Color _color = Colors.black.withOpacity(0.5);

  _buildLoading() {
    return SliverList(
      delegate: SliverChildListDelegate([
        Shimmer.fromColors(
          baseColor: Colors.grey[300].withOpacity(0.5),
          highlightColor: Colors.grey[100].withOpacity(0.5),
          direction: ShimmerDirection.ttb,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                color: _color,
                margin: EdgeInsets.all(8.0),
                width: 160,
                height: 80,
              ),
              Container(
                color: _color,
                margin: EdgeInsets.all(8.0),
                width: 200,
                height: 20,
              ),
              Container(
                color: _color,
                margin: EdgeInsets.all(8.0),
                width: 80,
                height: 30,
              ),
              Align(
                alignment: Alignment.centerLeft,
                child: Container(
                  color: _color,
                  margin: EdgeInsets.all(8.0),
                  width: 150,
                  height: 20,
                ),
              ),
              SizedBox(
                height: 120,
                child: ListView(
                  shrinkWrap: true,
                  scrollDirection: Axis.horizontal,
                  children: List.generate(
                      4,
                      (index) => Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: CircleAvatar(
                              backgroundColor: _color,
                              radius: MediaQuery.of(context).size.width * 0.12,
                            ),
                          )),
                ),
              ),
              Align(
                alignment: Alignment.centerLeft,
                child: Container(
                  color: _color,
                  margin: EdgeInsets.all(8.0),
                  width: 150,
                  height: 20,
                ),
              ),
              SizedBox(
                height: 120,
                child: ListView(
                  shrinkWrap: true,
                  scrollDirection: Axis.horizontal,
                  children: List.generate(
                    4,
                    (index) => Container(
                      height: 120,
                      width: 100,
                      color: _color,
                      margin: EdgeInsets.all(4.0),
                    ),
                  ),
                ),
              )
            ],
          ),
        )
      ]),
    );
  }
}

今天的效果注意看,有微光閃過
Day23

GitHub連結: flutter-netflix-clone


上一篇
[Day22]Flutter Netflix UI搜尋頁面之使用FadeInImage
下一篇
[Day24]Flutter Netflix UI 不讓底部導航欄消失,嘗試用Navigator 2.0
系列文
新手試試用Flutter做Netflix UI30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言