skip to Main Content

I have the following design in Figma that I want to implement in Flutter. The design is a Zig-Zag pattern that represents a progress indicator, where it moves towards the end. When a step is completed, a custom checkmark will appear on it, marking it as done. Here is the design:

The Design

I tried using the Paint class in Flutter, but it didn’t give me the desired result.

2

Answers


  1. I haven’t really put much work into this, it’s far from perfrect, but I hope that this helps. And warning, this code isn’t ‘clean’ and ‘efficient’ yet:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        const MyApp(),
      );
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: "Wavy UI",
          debugShowCheckedModeBanner: false,
          home: WavyUI(),
        );
      }
    }
    
    class WavyUI extends StatelessWidget {
      const WavyUI({super.key});
    
      @override
      Widget build(BuildContext context) {
        final double rangePerItem = 90;
    
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Stack(
            children: [
              Container(
                margin: EdgeInsets.only(top: rangePerItem * 0),
                child: WavyItem(
                  text: "Wavy 01",
                  wavyDirection: AxisDirection.right,
                ),
              ),
              Container(
                margin: EdgeInsets.only(top: rangePerItem * 1),
                child: WavyItem(
                  text: "Wavy 02",
                  wavyDirection: AxisDirection.left,
                ),
              ),
              Container(
                margin: EdgeInsets.only(top: rangePerItem * 2),
                child: WavyItem(
                  text: "Wavy 03",
                  wavyDirection: AxisDirection.right,
                ),
              ),
              Container(
                margin: EdgeInsets.only(top: rangePerItem * 3),
                child: WavyItem(
                  text: "Wavy 04",
                  wavyDirection: AxisDirection.left,
                ),
              ),
            ],
          ),
        );
      }
    }
    
    class WavyItem extends StatelessWidget {
      const WavyItem({
        super.key,
        required this.text,
        required this.wavyDirection,
      });
    
      final String text;
      final AxisDirection wavyDirection;
    
      BorderRadius _getBorderRadius(double circularRadius) {
        if (wavyDirection == AxisDirection.left) {
          return BorderRadius.only(
            topLeft: Radius.circular(circularRadius),
            bottomLeft: Radius.circular(circularRadius),
          );
          //
        } else {
          return BorderRadius.only(
            topRight: Radius.circular(circularRadius),
            bottomRight: Radius.circular(circularRadius),
          );
        }
      }
    
      @override
      Widget build(BuildContext context) {
        final Widget textWidget = Container(
          width: 100,
          height: 100,
          alignment: Alignment.center,
          child: Text(
            text,
            style: const TextStyle(fontSize: 15),
          ),
        );
    
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            (wavyDirection == AxisDirection.right) ? textWidget : const SizedBox.shrink(),
            Container(
              width: 100,
              height: 100,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: const Color.fromARGB(255, 110, 150, 220),
                borderRadius: _getBorderRadius(60),
              ),
              child: Container(
                width: 100,
                height: 80,
                margin: EdgeInsets.only(
                  right: (wavyDirection == AxisDirection.right) ? 10 : 0,
                  left: (wavyDirection == AxisDirection.right) ? 0 : 10,
                ),
                decoration: BoxDecoration(
                  color: Colors.black,
                  borderRadius: _getBorderRadius(60),
                ),
                child: const Icon(Icons.balance_outlined, color: Colors.white),
              ),
            ),
            (wavyDirection == AxisDirection.left) ? textWidget : const SizedBox.shrink(),
          ],
        );
      }
    }
    

    Thus, the result:
    Is this.

    Tweak it a little bit and you’ll achieve the desired UI. Cheers.

    Login or Signup to reply.
  2. I have tried zig-zag design with my logic check if that will meet your requirement

               Container(
                  color: Colors.white,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Container(
                            width: 100,
                            height: 80,
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.only(
                                    topLeft: Radius.circular(50),
                                    bottomLeft: Radius.circular(50)),
                                color: Colors.white),
                          ),
                          Container(
                            width: 100,
                            height: 80,
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.only(
                                    topRight: Radius.circular(50),
                                    bottomRight: Radius.circular(50)),
                                color: Colors.orange),
                          ),
                        ],
                      ),
                      Transform.translate(
                        offset: Offset(0, -10),
                        child: Container(
                          margin: EdgeInsets.only(left: 30),
                          width: 120,
                          height: 10,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.only(
                                  topRight: Radius.circular(0),
                                  bottomRight: Radius.circular(0)),
                              color: Colors.orange),
                        ),
                      ),
                      Transform.translate(
                        offset: Offset(0, -20),
                        child: Row(
                          children: [
                            Stack(alignment: Alignment.centerRight, children: [
                              Container(
                                width: 100,
                                height: 80,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.orange),
                              ),
                              Container(
                                width: 90,
                                height: 60,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.blue),
                              ),
                            ]),
                          ],
                        ),
                      ),
                      Row(
                        children: [
                          Container(
                            width: 100,
                            height: 80,
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.only(
                                    topLeft: Radius.circular(50),
                                    bottomLeft: Radius.circular(50)),
                                color: Colors.white),
                          ),
                          Transform.translate(
                            offset: Offset(0, -30),
                            child: Container(
                              width: 100,
                              height: 80,
                              decoration: BoxDecoration(
                                  borderRadius: BorderRadius.only(
                                      topRight: Radius.circular(50),
                                      bottomRight: Radius.circular(50)),
                                  color: Colors.orange),
                            ),
                          ),
                        ],
                      ),
                      Transform.translate(
                        offset: Offset(0, -40),
                        child: Row(
                          children: [
                            Stack(alignment: Alignment.centerRight, children: [
                              Container(
                                width: 100,
                                height: 80,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.orange),
                              ),
                              Container(
                                width: 90,
                                height: 60,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.blue),
                              ),
                            ]),
                          ],
                        ),
                      ),
                      Row(
                        children: [
                          Container(
                            width: 100,
                            height: 80,
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.only(
                                    topLeft: Radius.circular(50),
                                    bottomLeft: Radius.circular(50)),
                                color: Colors.white),
                          ),
                          Transform.translate(
                            offset: Offset(0, -50),
                            child: Container(
                              width: 100,
                              height: 80,
                              decoration: BoxDecoration(
                                  borderRadius: BorderRadius.only(
                                      topRight: Radius.circular(50),
                                      bottomRight: Radius.circular(50)),
                                  color: Colors.orange),
                            ),
                          ),
                        ],
                      ),
                      Transform.translate(
                        offset: Offset(0, -60),
                        child: Row(
                          children: [
                            Stack(alignment: Alignment.centerRight, children: [
                              Container(
                                width: 100,
                                height: 80,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.orange),
                              ),
                              Container(
                                width: 90,
                                height: 60,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(50),
                                        bottomLeft: Radius.circular(50)),
                                    color: Colors.blue),
                              ),
                            ]),
                          ],
                        ),
                      ),
                    ],
                  ),
                )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search