Flutter 中的 Shimmer 動畫效果
加載時間在應用程序改進中是不可避免的。從用戶體驗 (UX) 的角度來看,主要是向您的用戶展示正在加載。處理向用戶傳遞信息正在加載的一種主流方法是在不準確的加載物質類型的形狀上顯示帶有微光動畫的鉻色調。
在在這篇博客中,我們將探索 Flutter 中的 Shimmer 動畫效果。我們將看到如何實現微光動畫效果的演示程序,并在您的 Flutter 應用程序中使用shimmer包展示加載動畫效果。
什么是微光動畫效果?
Shimmer 用于在應用程序中從服務器加載內容時添加精彩的動畫。這使 UI 看起來更具響應性。它可以很好地被利用,而不是傳統(tǒng)的 ProgressBar 或 Flutter 結構中可訪問的常見loading。
通常,在我們打開應用程序的任何時候,我們都會看到具有動畫的loading。它演示了應用程序從服務器或本地數據庫加載信息。有多種方法可以顯示這種效果。在這種情況下,我們通常會在加載信息后對與第一個小部件完全相似的小部件進行動畫處理。

此演示視頻展示了如何在顫動中創(chuàng)建微光動畫效果。它展示了如何在 Flutter應用程序中使用shimmer包來實現微光動畫效果。它顯示代碼何時成功運行,然后顯示內容正在從虛擬數據加載是帶有持續(xù)時間的微光動畫效果,然后加載完成然后內容將顯示在您的設備上。
特性
微光動畫效果有一些屬性:
**baseColor:**顯示在 Widget 上的 Shimmer 的基本顏色。這種顏色是必不可少的,因為子小部件將采用這種顏色。 highlightColor: Highlight Color 是提供微光般效果的顏色。這種顏色繼續(xù)在子小部件上波動,并產生微光效果。 child: Child 擁有創(chuàng)建 ShimmerEffect 所需的任何小部件。可以是文本小部件或復雜的設計,并且創(chuàng)建 ShimmerEffect 沒有任何問題。 **direction:**您可以從左到右、從右到左、從開始到結束或從底到頂調整微光高光顏色的方向,為此,您只需傳遞具有確定方向的 ShimmerDirection。 **period:**它控制微光效果的速度。默認值為 1500 毫秒。
實現
添加依賴
shimmer: ^2.0.0導入
import 'package:shimmer/shimmer.dart';執(zhí)行 flutter packages get
創(chuàng)建一個 movie_model.dart 文件
class MovieModel {
final String urlImg;
final String title;
final String detail;
const MovieModel({required this.urlImg,
required this.title,
required this.detail});
}
我們將創(chuàng)建一個類**MovieModel。**在這個類中,我們將創(chuàng)建三個最終字符串,分別是 urlImg、title 和 detail。我們還創(chuàng)建了所有字符串項的構造函數。
創(chuàng)建一個 movie_data.dart 文件
import 'package:flutter_shimmer_animation/model/movie_model.dart';
List<MovieModel> allMovies =[
MovieModel(
urlImg:'https://gumlet.assettype.com/bloombergquint%2F2019-04%2F4c894d41-181f-4c8c-8630-4604a6d51d05%2Favengers_infinity_war_and_endgame_poster_w7_1600x900.jpg?rect=0%2C0%2C1250%2C900&auto=format%2Ccompress&w=480&dpr=2.6',
title:'Avengers: Endgame',
detail:'It s a 2019 American superhero film based '
),
MovieModel(
urlImg:'https://townsquare.media/site/442/files/2014/08/The-Expendables.jpg?w=980&q=75',
title:'The Expendables 3',
detail:'The Expendables 3 is a 2014 American action '
),
MovieModel(
urlImg:'https://img.etimg.com/thumb/msid-71454408,width-650,imgsize-242226,,resizemode-4,quality-100/war-1.jpg',
title:'War',
detail:'War is a 2019 Indian Hindi-language action '
),
MovieModel(
urlImg:'https://iadsb.tmgrup.com.tr/de9f7e/1200/627/0/0/1000/522?u=https://idsb.tmgrup.com.tr/2019/12/22/1577016105167.jpg',
title:'Jumanji: The Next Level',
detail:'Jumanji: The Next Level is a 2019 American '
),
MovieModel(
urlImg:'https://evertise.net/wp-content/uploads/2021/06/image-366.png',
title:'Fast & Furious 9',
detail:'Dom Toretto`s peaceful life off the grid.'
)
];
在這個 dart 文件中,我們將創(chuàng)建一個電影列表。我們將添加五個MovieModel 的虛擬數據**。**我們添加了 urlImg、title 和 detail 五個不同的數據。
創(chuàng)建一個 custom_widget.dart 文件
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
class CustomWidget extends StatelessWidget {
final double width;
final double height;
final ShapeBorder shapeBorder;
const CustomWidget.rectangular({
this.width = double.infinity,
required this.height
}): this.shapeBorder = const RoundedRectangleBorder();
const CustomWidget.circular({
this.width = double.infinity,
required this.height,
this.shapeBorder = const CircleBorder()
});
@override
Widget build(BuildContext context) => Shimmer.fromColors(
baseColor: Colors.red,
highlightColor: Colors.grey[300]!,
period: Duration(seconds: 2),
child: Container(
width: width,
height: height,
decoration: ShapeDecoration(
color: Colors.grey[400]!,
shape: shapeBorder,
),
),
);
}
創(chuàng)建一個 my_home_page.dart 文件,創(chuàng)建一個 List
List<MovieModel> movies = [];
bool isLoading = false;
@override
void initState() {
// TODO: implement initState
super.initState();
loadData();
}
Future loadData() async {
setState(() {
isLoading = true;
});
await Future.delayed(Duration(seconds: 2));
movies = List.of(allMovies);
setState(() {
isLoading = false;
});
}
創(chuàng)建一個buildMovieList()。在這個方法中,我們將添加 ListTile() 小部件。
Widget buildMovieList(MovieModel model) =>
ListTile(
leading: CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(model.urlImg),
),
title: Text(model.title, style: TextStyle(fontSize: 16),),
subtitle: Text(
model.detail, style: TextStyle(fontSize: 14), maxLines: 1,),
)
Widget buildMovieShimmer() =>
ListTile(
leading: CustomWidget.circular(height: 64, width: 64),
title: Align(
alignment: Alignment.centerLeft,
child: CustomWidget.rectangular(height: 16,
width: MediaQuery.of(context).size.width*0.3,),
),
subtitle: CustomWidget.rectangular(height: 14),
);
添加ListView.builder()。在里面,添加 itemCount 和 itemBuilder。在 itemBuilder 中,我們將添加條件 if isLoading 然后返回 buildMovieShimmer() 小部件,否則我們將返回最終電影等于電影 [index] 并返回 buildMovieList (movie);
ListView.builder(
itemCount: isLoading? 5: movies.length,
itemBuilder: (context, index) {
if (isLoading) {
return buildMovieShimmer();
} else {
final movie = movies[index];
return buildMovieList(movie);
}
}
),

當數據成功加載時,微光停止,所有數據將顯示在您的屏幕上。我們還將在 appBar() 上添加一個刷新按鈕以獲得微光效果。
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: loadData)
],

完整代碼
import 'package:flutter/material.dart';
import 'package:flutter_shimmer_animation/custom_widget.dart';
import 'package:flutter_shimmer_animation/data/movie_data.dart';
import 'package:flutter_shimmer_animation/model/movie_model.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<MovieModel> movies = [];
bool isLoading = false;
@override
void initState() {
// TODO: implement initState
super.initState();
loadData();
}
Future loadData() async {
setState(() {
isLoading = true;
});
await Future.delayed(Duration(seconds: 2));
movies = List.of(allMovies);
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.teal,
title: Text("Shimmer Animation Effect"),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: loadData)
],
),
body: ListView.builder(
itemCount: isLoading? 5: movies.length,
itemBuilder: (context, index) {
if (isLoading) {
return buildMovieShimmer();
} else {
final movie = movies[index];
return buildMovieList(movie);
}
}
),
);
}
Widget buildMovieList(MovieModel model) =>
ListTile(
leading: CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(model.urlImg),
),
title: Text(model.title, style: TextStyle(fontSize: 16),),
subtitle: Text(
model.detail, style: TextStyle(fontSize: 14), maxLines: 1,),
);
Widget buildMovieShimmer() =>
ListTile(
leading: CustomWidget.circular(height: 64, width: 64),
title: Align(
alignment: Alignment.centerLeft,
child: CustomWidget.rectangular(height: 16,
width: MediaQuery.of(context).size.width*0.3,),
),
subtitle: CustomWidget.rectangular(height: 14),
);
}
原文鏈接:https://medium.com/flutterdevs/explore-shimmer-animation-effect-in-flutter-7b0e46a9c722

