Home > Software engineering >  Need help to build custom widget in flutter
Need help to build custom widget in flutter

Time:01-11

Hey I try to create a custom widget like this, where I can change the text in the bottom part of the card. enter image description here

I already create the shape but I have no idea on how to place Text('Aktif'), I tried using Stack or Column but none works, any Idea?

Here is my code:

@override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Card(
          shape: CardShape(),
          elevation: 18,
          shadowColor: const Color.fromRGBO(51, 0, 0, 0.1),
          color: CustomStyle.primaryRed,
          child: Container(
            decoration: BoxDecoration(
                color: CustomStyle.white,
                border: Border.all(color: CustomStyle.primaryRed),
                borderRadius: BorderRadius.circular(8)),
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: ListTile(
              title: const Text('Rumah Tanggerang'),
              subtitle: const Text('Primary - 1234567890'),
              trailing: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Text(
                    'DEFAULT',
                  ),
                  myPopMenu()
                ],
              ),
            ),
          ),
        ),
        Positioned(left: 10, bottom: 0, child: Text('Aktif'))
      ],
    );
  }
class CardShape extends ShapeBorder {
  const CardShape();

  final BorderSide _side = BorderSide.none;
  final BorderRadiusGeometry _borderRadius = BorderRadius.zero;

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.all(_side.width);

  @override
  Path getInnerPath(
    Rect rect, {
    TextDirection? textDirection,
  }) {
    final Path path = Path();

    path.addRRect(
      _borderRadius.resolve(textDirection).toRRect(rect).deflate(_side.width),
    );

    return path;
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    final Path path = Path();
    final RRect rrect = _borderRadius.resolve(textDirection).toRRect(rect);

    path.moveTo(0, 10);
    path.quadraticBezierTo(0, 0, 10, 0);
    path.lineTo(rrect.width - 10, 0);
    path.quadraticBezierTo(rrect.width, 0, rrect.width, 10);
    path.lineTo(rrect.width, rrect.height - 10);
    path.quadraticBezierTo(
        rrect.width, rrect.height, rrect.width - 10, rrect.height);
    path.lineTo(100, rrect.height);
    path.lineTo(80, rrect.height   20);
    path.lineTo(10, rrect.height   20);
    path.quadraticBezierTo(0, rrect.height   20, 0, rrect.height   10);

    return path;
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}

  @override
  ShapeBorder scale(double t) => RoundedRectangleBorder(
        side: _side.scale(t),
        borderRadius: _borderRadius * t,
      );
}

CodePudding user response:

Card widget can't used stack because the red container is already outside the Card element so to put the text you just can wrap Stack inside of a Column and put the Text widget without position this is the example that I've already did

class Test extends StatelessWidget {
  const Test({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          decoration: const BoxDecoration(color: Colors.blue),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Stack(
                children: [
                  Card(
                    shape: const CardShape(),
                    elevation: 18,
                    shadowColor: const Color.fromRGBO(51, 0, 0, 0.1),
                    color: Colors.red,
                    child: Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.red),
                          borderRadius: BorderRadius.circular(8)),
                      padding: const EdgeInsets.symmetric(vertical: 8),
                      child: ListTile(
                        title: const Text('Rumah Tanggerang'),
                        subtitle: const Text('Primary - 1234567890'),
                        trailing: Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          mainAxisSize: MainAxisSize.min,
                          children: const <Widget>[
                            Text(
                              'DEFAULT',
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
              const Padding(
                padding: EdgeInsets.only(
                  left: 30,
                ),
                child: Text(
                  'Aktif',
                  style: TextStyle(
                      color: Colors.white, fontWeight: FontWeight.w700),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

if you copy my code just made sure to change back the color you've used.

enter image description here

  • Related