Skip to content

Instantly share code, notes, and snippets.

@hnvn
Last active September 15, 2019 04:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hnvn/6624c02f719d8753c6802f2090e767ce to your computer and use it in GitHub Desktop.
Save hnvn/6624c02f719d8753c6802f2090e767ce to your computer and use it in GitHub Desktop.
class _ShimmerState extends State<Shimmer> with TickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: widget.period)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.repeat();
}
});
controller.forward();
}
@override
Widget build(BuildContext context) {
return _Shimmer(
child: widget.child,
gradient: widget.gradient,
percent: controller.value,
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
class _Shimmer extends SingleChildRenderObjectWidget {
...
final double percent;
_Shimmer({Widget child, this.gradient, this.percent})
: super(child: child);
@override
_ShimmerFilter createRenderObject(BuildContext context) {
return _ShimmerFilter(percent, gradient);
}
@override
void updateRenderObject(BuildContext context, _ShimmerFilter shimmer) {
shimmer.percent = percent;
}
}
class _ShimmerFilter extends RenderProxyBox {
...
double _percent;
_ShimmerFilter(this._percent, this._gradient)
: _gradientPaint = Paint()..blendMode = BlendMode.srcIn;
...
set percent(double newValue) {
if (newValue != _percent) {
_percent = newValue;
markNeedsPaint();
}
}
@override
void paint(PaintingContext context, Offset offset) {
if (child != null) {
assert(needsCompositing);
final width = child.size.width;
final height = child.size.height;
Rect rect;
double dx, dy;
dx = _offset(-width, width, _percent);
dy = 0.0;
rect = Rect.fromLTWH(offset.dx - width, offset.dy, 3 * width, height);
_gradientPaint.shader = _gradient.createShader(rect);
context.canvas.saveLayer(offset & child.size, _clearPaint);
context.paintChild(child, offset);
context.canvas.translate(dx, dy);
context.canvas.drawRect(rect, _gradientPaint);
context.canvas.restore();
}
}
double _offset(double start, double end, double percent) {
return start + (end - start) * percent;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment