Skip to content

Instantly share code, notes, and snippets.

@hugeorange
Created June 3, 2023 08:47
Show Gist options
  • Save hugeorange/adb11487d8803cbd6aa3338cc399204c to your computer and use it in GitHub Desktop.
Save hugeorange/adb11487d8803cbd6aa3338cc399204c to your computer and use it in GitHub Desktop.
Flutter Overlay 创建自定义 Loading
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:tablet/components/text/index.dart';
class Loading {
static int duration = 2500;
static OverlayEntry? _overlayEntry;
static final GlobalKey<_LoadingAnimationState> _loadingStateKey =
GlobalKey<_LoadingAnimationState>();
static void show() {
Future.delayed(Duration.zero).then((value) => _show(context: Get.context!));
}
static void hide() async {
await _loadingStateKey.currentState?.dismiss();
_overlayEntry?.remove();
_overlayEntry = null;
}
static void _show({required BuildContext context}) {
if (_overlayEntry != null) {
return;
}
_overlayEntry = OverlayEntry(
builder: (ctx) => _LoadingAnimation(
key: _loadingStateKey,
child: const _LoadingBody(),
),
);
Overlay.of(context).insert(_overlayEntry!);
}
}
// loading 动画模板样式
class _LoadingBody extends StatelessWidget {
const _LoadingBody();
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.black,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
SpinKitWave(color: Colors.white, size: 40.0),
SizedBox(height: 8),
RText('loading...', color: Colors.white),
],
),
);
}
}
// loading 动画核心
class _LoadingAnimation extends StatefulWidget {
const _LoadingAnimation({super.key, required this.child});
final Widget child;
@override
State<_LoadingAnimation> createState() => _LoadingAnimationState();
}
class _LoadingAnimationState extends State<_LoadingAnimation> {
double _opacity = 0;
@override
void initState() {
Future.delayed(Duration.zero).then((value) => setState(() => _opacity = 1));
super.initState();
}
Future dismiss() {
setState(() => _opacity = 0);
return Future.delayed(const Duration(milliseconds: 250));
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Positioned(
top: 0,
left: 0,
right: 0,
bottom: 0,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 250),
opacity: _opacity,
child: Container(
color: const Color.fromRGBO(0, 0, 0, 0.7),
child: Center(child: widget.child),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment