juliuscanute / qr_code_scanner

QR Code Scanner for Flutter
BSD 2-Clause "Simplified" License
999 stars 759 forks source link

[FEATURE] Could we add Line in Camera QR view? #501

Open john-smith-rk opened 2 years ago

john-smith-rk commented 2 years ago

image

Could we add like above image ?

evan-mcgeek commented 2 years ago

might be a bit late, but for anyone who might want to use it here is the widget for that.

Usage:

Stack( alignment: Alignment.bottomRight, children: [ QrView(...), MovingScanLine(...) ])

class MovingScanLine extends StatefulWidget {
  const MovingScanLine({
    required this.color,
    required this.successColor,
    required this.isLoading,
    required this.isSuccess,
    required this.height,
    Key? key,
  }) : super(key: key);

  final Color color;
  final Color successColor;
  final bool isLoading;
  final double height;
  final bool isSuccess;

  @override
  State<MovingScanLine> createState() => _MovingScanLineState();
}

class _MovingScanLineState extends State<MovingScanLine> with SingleTickerProviderStateMixin<MovingScanLine> {
  late AnimationController _animationController;
  late Animation<double> _animation;

  @override
  void initState() {
    _animationController = AnimationController(vsync: this, duration: const Duration(seconds: 2))..forward();

    _animationController
      ..addStatusListener((AnimationStatus status) {
        if (status == AnimationStatus.completed) {
          _animationController.reverse(from: 1);
        } else if (status == AnimationStatus.dismissed) {
          _animationController.forward(from: 0);
        }
      })
      ..addListener(() {
        if (widget.isSuccess || widget.isLoading) {
          _animationController.stop();
        }
        setState(() {});
      });

    _animation = Tween<double>(begin: 0, end: 1).animate(_animationController);

    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      bottom: _animation.value * widget.height,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 200),
        height: widget.isSuccess ? 2 : 1,
        width: MediaQuery.of(context).size.width,
        color: (widget.isSuccess ? widget.successColor : widget.color).withOpacity(0.5),
      ),
    );
  }
}