1

I'm trying to make a custom animated progress indicator like this one

but I don't know where to start..

Appreciate the help thanks!

Loading image

edit: with flutter only if possible

1
  • I prefer rive. or may customPainter can help in this case. Commented Sep 1, 2021 at 3:02

2 Answers 2

6
+100

You can use ClipPath and CustomPaint like this:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();

    controller = AnimationController(duration: const Duration(milliseconds: 1000), vsync: this);
    controller.addStatusListener(statusListener);
    controller.forward();
  }

  statusListener(AnimationStatus status) {
    if (status == AnimationStatus.completed) {
      controller.value = 0.0;
      controller.forward();
    }
  }

  @override
  void dispose() {
    controller.removeStatusListener(statusListener);
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Container(
        width: 200,
        height: 200,
        color: Colors.blue,
        child: Center(
          child: AnimatedBuilder(
              animation: controller.view,
              builder: (context, snapshot) {
                return ClipPath(
                  clipper: MyClipper(),
                  child: Container(
                    width: 100,
                    height: 100,
                    color: Colors.white,
                    child: CustomPaint(
                      painter: MyCustomPainter(controller.value),
                    ),
                  ),
                );
              }),
        ),
      )),
    );
  }
}

class MyClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    double w = size.width;
    double h = size.height;

    Path path = Path();
    path.moveTo(w / 2, 0);
    path.lineTo(w / 2 - 20, 55);
    path.lineTo(w / 2, 55);
    path.lineTo(w / 2 - 20, h);
    path.lineTo(w / 2 + 20, 45);
    path.lineTo(w / 2, 45);
    path.lineTo(w / 2 + 20, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper oldClipper) {
    return false;
  }
}

class MyCustomPainter extends CustomPainter {
  final double percentage;

  MyCustomPainter(this.percentage);
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.amber
      ..style = PaintingStyle.fill;

    Rect rect = Rect.fromLTWH(0, 0, size.width, size.height * percentage);

    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

enter image description here

Sign up to request clarification or add additional context in comments.

4 Comments

Hi @Develocode 777 can you tell me how to loop the value? since I just a spinner that constantly moving Thanks!!
Hi, i edited my answer to make the loading loop.
Thank you very much!! will study up on this :)
Glad to have helped!
3

I don't know you can control lotti asset and package.
https://pub.dev/packages/lottie

With lotti asset, you can make a loading indicator page like below.

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lottie/lottie.dart';

class LoadingIndicatorPage extends StatelessWidget {
  final Color backgroundColor;
  LoadingIndicatorPage({this.backgroundColor});

  @override
  Widget build(BuildContext context) => Container(
        color: backgroundColor ?? Colors.transparent,
        child: Center(
          child: Lottie.asset(
            'assets/loading_indicator3.zip',
            width: ScreenUtil().setWidth(64),
            height: ScreenUtil().setWidth(64),
          ),
        ),
      );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.