Flutter占位骨架屏插件easy_skeleton的使用
Flutter占位骨架屏插件easy_skeleton的使用
在本教程中,我们将学习如何在Flutter项目中使用easy_skeleton
插件来实现占位骨架屏。此插件可以帮助我们在网络请求或数据加载期间展示一个动态的占位屏幕,以提高用户体验。
安装
首先,在你的pubspec.yaml
文件中添加easy_skeleton
依赖:
dependencies:
easy_skeleton: ^1.0.0
然后运行flutter pub get
命令来安装该依赖。
使用
接下来,我们将通过一个简单的示例来演示如何使用easy_skeleton
插件。
示例代码
import 'package:easy_skeleton/easy_skeleton.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Skeleton Demo',
theme: ThemeData(primarySwatch: Colors.teal),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
builder: (_, child) {
return SkeletonManager(
viewMode: SkeletonViewMode.auto,
theme: SkeletonThemeData(color: Colors.grey, radius: 4),
// darkTheme: SkeletonThemeData(color: Colors.amber, radius: 4),
// groupBuilder: (context, child) {
// final color = SkeletonTheme.of(context).color;
//
// return Shimmer.fromColors(
// baseColor: color!,
// highlightColor: color.withOpacity(0.8),
// child: child,
// );
// },
child: child!,
);
},
home: const SkeletonDemoPage(),
);
}
}
class InvertedTheme extends StatelessWidget {
final Widget child;
const InvertedTheme({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
var app = context.findAncestorWidgetOfExactType<MaterialApp>();
if (app != null && app.theme != null && app.darkTheme != null) {
var isDark = Theme.of(context).brightness == Brightness.dark;
var brightness = isDark ? Brightness.light : Brightness.dark;
var themeData = isDark ? app.theme : app.darkTheme;
return Theme(
data: themeData!.copyWith(brightness: brightness),
child: child,
);
}
return child;
}
}
代码解释
-
导入库:
import 'package:easy_skeleton/easy_skeleton.dart'; import 'package:flutter/material.dart';
-
主应用类:
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Skeleton Demo', theme: ThemeData(primarySwatch: Colors.teal), darkTheme: ThemeData.dark(), themeMode: ThemeMode.system, builder: (_, child) { return SkeletonManager( viewMode: SkeletonViewMode.auto, theme: SkeletonThemeData(color: Colors.grey, radius: 4), // darkTheme: SkeletonThemeData(color: Colors.amber, radius: 4), // groupBuilder: (context, child) { // final color = SkeletonTheme.of(context).color; // // return Shimmer.fromColors( // baseColor: color!, // highlightColor: color.withOpacity(0.8), // child: child, // ); // }, child: child!, ); }, home: const SkeletonDemoPage(), ); } }
SkeletonManager
是用于管理骨架屏的核心组件。viewMode
设置为SkeletonViewMode.auto
,表示根据当前主题自动选择骨架屏样式。theme
和darkTheme
分别定义了默认主题和暗黑主题下的骨架屏颜色和圆角半径。child
参数是实际的应用页面。
-
主题切换类:
class InvertedTheme extends StatelessWidget { final Widget child; const InvertedTheme({Key? key, required this.child}) : super(key: key); @override Widget build(BuildContext context) { var app = context.findAncestorWidgetOfExactType<MaterialApp>(); if (app != null && app.theme != null && app.darkTheme != null) { var isDark = Theme.of(context).brightness == Brightness.dark; var brightness = isDark ? Brightness.light : Brightness.dark; var themeData = isDark ? app.theme : app.darkTheme; return Theme( data: themeData!.copyWith(brightness: brightness), child: child, ); } return child; } }
更多关于Flutter占位骨架屏插件easy_skeleton的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter占位骨架屏插件easy_skeleton的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用easy_skeleton
插件来实现占位骨架屏效果的代码示例。easy_skeleton
是一个流行的Flutter插件,用于在数据加载时显示占位骨架屏,从而提升用户体验。
首先,你需要在你的pubspec.yaml
文件中添加easy_skeleton
依赖:
dependencies:
flutter:
sdk: flutter
easy_skeleton: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们来看一个具体的代码示例,展示如何使用easy_skeleton
来实现占位骨架屏:
import 'package:flutter/material.dart';
import 'package:easy_skeleton/easy_skeleton.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Easy Skeleton Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends HookWidget {
final _controller = useState<bool>(true); // 控制骨架屏的显示
@override
Widget build(BuildContext context) {
final isLoading = _controller.value;
return Scaffold(
appBar: AppBar(
title: Text('Easy Skeleton Demo'),
),
body: Center(
child: isLoading
? SkeletonScreen(
// 自定义骨架屏布局
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SkeletonWidget(
width: double.infinity,
height: 50,
margin: EdgeInsets.symmetric(vertical: 10),
),
SkeletonWidget(
width: double.infinity,
height: 20,
shape: BoxShape.circle,
margin: EdgeInsets.symmetric(vertical: 10),
),
SkeletonWidget(
width: double.infinity,
height: 100,
margin: EdgeInsets.symmetric(vertical: 10),
),
],
),
)
: FutureBuilder<void>(
future: _simulateDataLoading(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // 或者继续使用骨架屏
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Name: John Doe', style: TextStyle(fontSize: 24)),
SizedBox(height: 10),
CircleAvatar(
backgroundImage: NetworkImage('https://via.placeholder.com/150'),
radius: 30,
),
SizedBox(height: 10),
Text('Description: A short description about John Doe.', style: TextStyle(fontSize: 16)),
],
);
}
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 切换骨架屏显示状态
_controller.value = !_controller.value;
// 重新触发数据加载模拟
_simulateDataLoading();
},
tooltip: 'Toggle Skeleton',
child: Icon(isLoading ? Icons.visibility_off : Icons.visibility),
),
);
}
Future<void> _simulateDataLoading() async {
// 模拟数据加载延迟
await Future.delayed(Duration(seconds: 2));
// 切换骨架屏显示状态
_controller.value = false;
}
}
在这个示例中:
- 我们使用了
easy_skeleton
提供的SkeletonWidget
和SkeletonScreen
来创建占位骨架屏。 SkeletonWidget
用于创建单个骨架元素,如文本占位符或圆形图片占位符。SkeletonScreen
用于将多个SkeletonWidget
组合成一个完整的骨架屏布局。- 通过
FutureBuilder
模拟了一个异步数据加载过程,并在数据加载完成之前显示骨架屏。 - 使用
useState
钩子来控制骨架屏的显示与隐藏,并通过点击浮动操作按钮来切换显示状态。
希望这个示例能够帮助你理解如何在Flutter项目中使用easy_skeleton
插件来实现占位骨架屏效果。