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
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;
}
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;
}
}