0

I've spent a lot of time googling on how I can achieve this but failed, maybe I'm googling it wrong, I tried using path, but failed.

I just want all items to change colors only when pressed, and the center docked will retain its shape and everything.

Please anyone who can shade some lights on this will be appreciated. Thank you

enter image description here

Here what I've tried to put together with google help. I just want to get exactly like what is shown on the attachment but my knowledge is limited at the moment.

 return Scaffold(
          backgroundColor: Color(0xFFFFFFFF),
          bottomNavigationBar: Material(
            color: Colors.transparent,
            elevation: 100,
            child: ClipPath(
              child: SizedBox(
                child: Container(
                    decoration: BoxDecoration(
                      color: Colors.white,
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: <Widget>[
                        IconButton(
                            icon: Icon(
                              Icons.home,
                              color: Colors.deepPurple,
                              size: 30,
                            ),
                            onPressed: () {
                              setState() {}
                            }),
                        IconButton(
                            icon: Icon(
                              Icons.branding_watermark,
                              size: 30,
                              color: Colors.black54,
                            ),
                            onPressed: () {}),
                        SizedBox(
                          width: 50,
                        ),
                        IconButton(
                            icon: Icon(
                              Icons.cloud_download,
                              size: 30,
                              color: Colors.black54,
                            ),
                            onPressed: () {}),
                        IconButton(
                            icon: Icon(
                              Icons.face,
                              size: 30,
                              color: Colors.black54,
                            ),
                            onPressed: () {}),
                      ],
                    )),
                height: 100,
                width: double.infinity,
              ),
              clipper: CurveDraw(),
            ),
          ),
          floatingActionButton: MaterialButton(
            color: Colors.deepPurple,
            padding: EdgeInsets.all(20),
            onPressed: () {},
            shape: CircleBorder(),
            child: Icon(
              Icons.add,
              size: 35,
              color: Colors.white,
            ),
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        );

Curve

getClip(Size size) {
    double sw = size.width;
    double sh = size.height;
    double gapConst = 50;
    Path path = Path();
    path.moveTo(0, sh);
    path.lineTo(0, sh / 2);
    path.quadraticBezierTo(0, 0, sh / 2, 0); //1st curve
    path.lineTo(sw / 2 - sw / 5, 0);
    path.cubicTo(sw / 2 - sw / 8, 0, sw / 2 - sw / 8, sh / 2, sw / 2, sh / 2);
    path.cubicTo(
        sw / 2 + sw / 8, sh / 2, sw / 2 + sw / 8, 0, sw / 2 + sw / 5, 0);

    path.lineTo(sw - sh / 2, 0);

    path.quadraticBezierTo(sw, 0, size.width, sh / 2);
    path.lineTo(sw, sh);
    path.close();

    // rotate the path around the x-axis (flip it upside down)
    path.transform(Matrix4.rotationX(pi));

    return path;
  }
  • try this package fancy_bottom_navigation https://pub.dev/packages/fancy_bottom_navigation – Munsif Ali Jan 16 '23 at 23:11
  • Thank you very much, using that plugin will not put the floating bottom docked at the center always. But will move whenever user clicks on the menu which is not the effect I am looking for.. I just want all items to change only colors when pressed, so the center docked will retain its shape and everything. – Frank Slayer Jan 16 '23 at 23:23
  • check out this https://pub.dev/packages/floating_bottom_bar – Munsif Ali Jan 16 '23 at 23:31
  • This is really helpful @MunsifAli that is close to what I need, what lacks there’s the shape of the floating button how have exactly shape like on the image.. thank you very much. – Frank Slayer Jan 16 '23 at 23:59

1 Answers1

0

I have implemented this bottom navigation bar without any 3rd party dependency, you can check this out:

Also don't forget to add vector_math dependecy in your pubspec and this import line at the top of the widget:

import 'package:vector_math/vector_math.dart' show radians;

class DemoWidget extends StatefulWidget {
  const DemoWidget({super.key});

  @override
  State<DemoWidget> createState() => _DemoWidgetState();
}

class _DemoWidgetState extends State<DemoWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 82, 49, 49),
      bottomNavigationBar: Container(
          height: 100,
          width: double.infinity,
          decoration: const BoxDecoration(
            color: Colors.white,
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              IconButton(
                  icon: const Icon(
                    Icons.home,
                    color: Colors.deepPurple,
                    size: 30,
                  ),
                  onPressed: () {
                    setState() {}
                  }),
              IconButton(
                  icon: const Icon(
                    Icons.branding_watermark,
                    size: 30,
                    color: Colors.black54,
                  ),
                  onPressed: () {}),
              const SizedBox(
                width: 50,
              ),
              IconButton(
                  icon: const Icon(
                    Icons.cloud_download,
                    size: 30,
                    color: Colors.black54,
                  ),
                  onPressed: () {}),
              IconButton(
                  icon: const Icon(
                    Icons.face,
                    size: 30,
                    color: Colors.black54,
                  ),
                  onPressed: () {}),
            ],
          )),
      floatingActionButton: CustomPaint(
        painter: HalfPainter(Colors.white),
        child: Padding(
          padding: const EdgeInsets.only(left: 18, right: 18, top: 30),
          child: MaterialButton(
            color: Colors.deepPurple,
            padding: const EdgeInsets.all(20),
            onPressed: () {},
            shape: const CircleBorder(),
            child: const Icon(
              Icons.add,
              size: 35,
              color: Colors.white,
            ),
          ),
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

class HalfPainter extends CustomPainter {
  HalfPainter(Color paintColor) {
    this.arcPaint = Paint()..color = paintColor;
  }

  late Paint arcPaint;

  @override
  void paint(Canvas canvas, Size size) {
    final Rect beforeRect = Rect.fromLTWH(0, (size.height / 2) - 10, 10, 10);
    final Rect largeRect = Rect.fromLTWH(10, 16, size.width - 20, 73);
    final Rect afterRect =
        Rect.fromLTWH(size.width - 10, (size.height / 2) - 10, 10, 10);

    final path = Path();
    path.arcTo(beforeRect, radians(0), radians(90), false);
    path.lineTo(20, size.height / 2);
    path.arcTo(largeRect, radians(0), -radians(180), false);
    path.moveTo(size.width - 10, size.height / 2);
    path.lineTo(size.width - 10, (size.height / 2) - 20);
    path.arcTo(afterRect, radians(180), radians(-100), false);
    path.close();

    canvas.drawPath(path, arcPaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
Cavin Macwan
  • 1,183
  • 5
  • 12
  • Thank you @cavin, how can I achieve the curves please see the screenshot https://snipboard.io/2nxDuo.jpg I want to achieve exactly like that.. – Frank Slayer Jan 17 '23 at 08:46
  • I have updated the example, do check it out and let me know if you need any help – Cavin Macwan Jan 17 '23 at 09:32
  • Thank you very much @Cavin, you helped me a lot, and your solution is superb, please assist me on the curve part to match the image on my original post, with the the solution you've updated, or show me where I can update(lower or upgrade ) the numbers of the conners. please see the screenshot https://snipboard.io/gWUm8d.jpg, I real real I appreciate what you've helped me – Frank Slayer Jan 17 '23 at 10:15
  • Hello @FrankSlayer, I have updated the code again to make the design as same as possible using custom painter. Please let me know if my answer helped you out. If so, I would appreciate if you could accept/upvote my answer If you still have questions, feel free to ask here – Cavin Macwan Jan 17 '23 at 11:08
  • Thank you @Cavin for your time on solving this, just quick pointer on this if possible to do like this I don't know if your adding a line or what please see https://snipboard.io/97B4Hg.jpg, the idea is to remove the circle feeling of it and make it look like it's part of the navigation container – Frank Slayer Jan 17 '23 at 12:01
  • Hello @FrankSlayer, As you can see in the code: I have wrapped the padding widget around the MaterialButton, You can change the left and right padding to achieve the results you want. Also, I would appreciate if you could accept/upvote my answer If you still have questions, feel free to ask here – Cavin Macwan Jan 17 '23 at 12:31
  • Thank you for your help till now, I have tried to increasing the padding but it's not removing the hard curve, https://snipboard.io/iHxUra.jpg.. all in all your answers are the best brother. – Frank Slayer Jan 17 '23 at 13:59
  • Hello @FrankSlayer, I have tried to solve it but this is the only solution that could work as of now, but I will research into it and find the exact answer of it. Till then if this solution helped you with your issue then you can consider giving upvote so that other people can also solve issues like this. Feel free to ask any questions if you have any – Cavin Macwan Jan 17 '23 at 18:05
  • Thank you very much @Cavin for your assistance on this, I really appreciate, be blessed. – Frank Slayer Jan 17 '23 at 18:13