Spa*_*000 6 dart flutter lottie
我有一个 Lottie 动画,用作加载屏幕:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:lottie/lottie.dart';
class Loading extends StatelessWidget {
final String loadingText;
Loading({this.loadingText});
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (loadingText != null) _buildLoadingText(loadingText),
_buildAnimation(),
],
),
);
}
Widget _buildLoadingText(String text) {
return Text(
loadingText,
style: GoogleFonts.poppins(
textStyle:
TextStyle(fontWeight: FontWeight.w500, color: Colors.black)),
);
}
Widget _buildAnimation() {
return Lottie.asset('assets/lottie/heartbeat_loading.json',
width: 300, repeat: true, animate: true);
}
}
Run Code Online (Sandbox Code Playgroud)
当我的应用程序最初加载时,我会这样使用它:
_determineHome() {
return StreamBuilder(
stream: AppBlocContainer().authenticationBloc().loggedIn,
builder: (context, AsyncSnapshot<AuthenticationStatus> snapshot) {
// return Loading();
return AnimatedSwitcher(
duration: Duration(seconds: 2),
child: !snapshot.hasData
? Loading(
loadingText: 'Loading...',
)
: _buildSecondChild(snapshot.data));
},
);
Run Code Online (Sandbox Code Playgroud)
这是可行的,除了 Lottie 动画加载可能晚了一两秒,当 Lottie 资源加载时,已经太晚了,页面已经转换了。
我想知道我是否能够main()通过这样做来预先缓存我的 SVG 图像:
Future.wait([
precachePicture(
ExactAssetPicture(
SvgPicture.svgStringDecoder, 'assets/svg/login.svg'),
null,
),
precachePicture(
ExactAssetPicture(
SvgPicture.svgStringDecoder, 'assets/svg/logo.svg'),
null,
),
precachePicture(
ExactAssetPicture(
SvgPicture.svgStringDecoder, 'assets/svg/signup_panel_1.svg'),
null,
)
]);
Run Code Online (Sandbox Code Playgroud)
我能对洛蒂做同样的事情吗?
我发现flutter中的lottie包本身有一个内置的自动缓存。(无论是否想要它都会将动画缓存到内存中)
方法A(自己制作):所以你基本上需要调用Lottie.asset('assets/Logo.json')一次,第二次你就可以通过调用Lottie.asset('assets/Logo.json')来毫不延迟地加载它。 json') 再次,因为它是第一次缓存。所以这可以用作作弊缓存方法,例如,您可以首先在启动屏幕中加载它,如下所示:通过使用 SizedBox 包装并给出 0 高度/宽度或使用可见性小部件,其可见属性为 false 但 keepState 为 true,所以它不可见,但仍然会在小部件树中并加载到内存中。
Visibility(
visible: false,
maintainSize: false,
maintainState: true,
maintainAnimation: false,
maintainInteractivity: false,
child: Row(
children: [
Lottie.asset('assets/Logo.json'),
],
),
),
Run Code Online (Sandbox Code Playgroud)
下次您需要时只需调用 Lottie.asset('assets/Logo.json') 即可立即加载。
方法B:这是github上一个叫Pante的人提到的。
class LottieCache {
final Map<String, LottieComposition> _compositions = {};
/// Caches the given [LottieAsset]s.
Future<void> add(String assetName) async {
_compositions[assetName] = await AssetLottie(assetName).load();
}
Widget load(String assetName, Widget fallback) {
final composition = _compositions[assetName];
return composition != null ? Lottie(composition: composition) : fallback;
}
}
Run Code Online (Sandbox Code Playgroud)
这里有两种方法:1)使用AssetLottie(assetName).load()方法;提供 LottieCache 对象,以便在需要时访问其加载方法。2)完全忽略load方法和合成方式(可以注释掉load方法);因为AssetLottie(assetName).load()将动画加载到ram中,就像Lottie.asset('assets/Logo.json')一样因此,只需调用其 add 方法即可将动画加载到 ram 中,您可以在下次需要时立即使用它。
方法C:这是lottie文档中提到的flutter的自定义加载方法。
class _MyWidgetState extends State<MyWidget> {
late final Future<LottieComposition> _composition;
@override
void initState() {
super.initState();
_composition = _loadComposition();
}
Future<LottieComposition> _loadComposition() async {
var assetData = await rootBundle.load('assets/LottieLogo1.json');
return await LottieComposition.fromByteData(assetData);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<LottieComposition>(
future: _composition,
builder: (context, snapshot) {
var composition = snapshot.data;
if (composition != null) {
return Lottie(composition: composition);
} else {
return const Center(child: CircularProgressIndicator());
}
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2683 次 |
| 最近记录: |