Easiest way to make a skeleton screen when data is loading. You can combine a Stack and Positioned.fill with a FractionallySizedBox to position such gradient on the top of another widget.
Then you can combine it to an AnimationController, an AnimatedBuilder and an Align or FractionallySizedBox to animate the position of the gradient over time.
Here is a quick example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | class LoadAnimation extends StatefulWidget { final Widget child; LoadAnimation({@required this.child, Key key}) : super(key: key); @override _LoadAnimationState createState() => _LoadAnimationState(); } class _LoadAnimationState extends State<LoadAnimation> with SingleTickerProviderStateMixin { AnimationController controller; @override void initState() { controller = AnimationController( vsync: this, duration: const Duration(seconds: 1), )..repeat(); super.initState(); } @override Widget build(BuildContext context) { return Stack( children: <Widget>[ widget.child, Positioned.fill( child: ClipRect( child: AnimatedBuilder( animation: controller, builder: (context, child) { return FractionallySizedBox( widthFactor: .2, alignment: AlignmentGeometryTween( begin: Alignment(-1.0 - .2 * 3, .0), end: Alignment(1.0 + .2 * 3, .0), ).chain(CurveTween(curve: Curves.easeOut)).evaluate(controller), child: child, ); }, child: const DecoratedBox( decoration: const BoxDecoration( gradient: const LinearGradient( colors: const [ Color.fromARGB(0, 255, 255, 255), Colors.white, ], ), ), ), )), ), ], ); } } |
Which you can then use by wrapping any given widget :
1 2 3 4 5 6 7 | LoadAnimation( child: Container( height: 100.0, width: 200.0, color: Colors.lime, ), ), |
If you like this question & answer and want to contribute, then write your question & answer and email to freewebmentor[@]gmail.com. Your question and answer will appear on FreeWebMentor.com and help other developers.