7

I stumbled upon this design in dribble enter image description here

and in trying to implement it in flutter I was able to create the curves using clip Path. this is what I haveenter image description here

I am trying to get rid of the space in between the shapes so that they can collapse.

this is my CurvedRectangleClipper:` import 'package:flutter/material.dart';

class CurvedRectangleClipper extends CustomClipper<Path> {
final double offset = 80;
@override
Path getClip(Size size) {
    // TODO: implement getClip
    Path path = Path();
    path.lineTo(0, size.height - offset);
    var firstEndpoint = Offset(offset, size.height);
    path.arcToPoint(firstEndpoint, radius: Radius.circular(-offset),clockwise: false);

    path.lineTo(size.width, size.height);
    path.lineTo(size.width, offset);
    path.lineTo(offset, offset);

    var secondEndPoint = Offset(0,0);

    path.arcToPoint(secondEndPoint, radius: Radius.circular(-offset),clockwise: true);
    path.lineTo(0, 0);
    path.close();
    return path;
}

@override
bool shouldReclip(CustomClipper oldClipper) {
    // TODO: implement shouldReclip
    return true;
}
}

and this is my main.dart file: import 'package:devotion/CurvedRectangleClipper.dart'; import 'package:flutter/material.dart';

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

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
    return MaterialApp(
    home: MainScreen(),
    title: 'Devotion',
    theme: appTheme,
    );
}
}

var appTheme =
    ThemeData(fontFamily: 'Oxygen', primaryColor: Colors.purpleAccent);

class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
        title: Text('Devotion'),
    ),
    body: ListView(
        scrollDirection: Axis.vertical,
        children: <Widget>[
        CurvedListItem(
            title: 'Yoga and Meditation for Beginners',
            time: 'TODAY 5:30 PM'),
        CurvedListItem(
            title: 'Practice French, English And Chinese',
            time: 'TUESDAY 5:30 PM',
        ),
        CurvedListItem(
            title: 'Adobe XD Live Event in Europe',
            time: 'FRIDAY 6:00 PM',
        ),
        ],
    ),
    );
}
}

class CurvedListItem extends StatelessWidget {
final String title;
final String time;
final String people;
final IconData icon;

CurvedListItem({this.title, this.time, this.icon, this.people});

@override
Widget build(BuildContext context) {
    return ClipPath(
    clipper: CurvedRectangleClipper(),
    child: Container(
        color: Colors.pink,
        padding: EdgeInsets.only(
        left: 32,
        top: 100,
        bottom: 50,
        ),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
            Text(
                time,
                style: TextStyle(color: Colors.white, fontSize: 12),
            ),
            SizedBox(
                height: 2,
            ),
            Text(
                title,
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 22,
                    fontWeight: FontWeight.bold),
            ),
            Row(),
            ]),
    ),
    );
}
}

` I guess the top curve is not needed if the items are placed on each other but I left it there to know the actual shape. Corrections and comments are also welcome. Thanks in advance.

2 Answers 2

25

AFAIK, you cannot get rid of the space between the clipped widgets. There is a easy and different approach you can take to solve this.

Here is how I would have done it:

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MainScreen(),
      title: 'Devotion',
      theme: appTheme,
    );
  }
}

ThemeData appTheme = ThemeData(
  fontFamily: 'Oxygen',
  primaryColor: Colors.purpleAccent,
);

class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Devotion'),
      ),
      body: ListView(
        scrollDirection: Axis.vertical,
        children: <Widget>[
          CurvedListItem(
            title: 'Yoga and Meditation for Beginners',
            time: 'TODAY 5:30 PM',
            color: Colors.red,
            nextColor: Colors.green,
          ),
          CurvedListItem(
            title: 'Practice French, English And Chinese',
            time: 'TUESDAY 5:30 PM',
            color: Colors.green,
            nextColor: Colors.yellow,
          ),
          CurvedListItem(
            title: 'Adobe XD Live Event in Europe',
            time: 'FRIDAY 6:00 PM',
            color: Colors.yellow,
          ),
        ],
      ),
    );
  }
}

class CurvedListItem extends StatelessWidget {
  const CurvedListItem({
    this.title,
    this.time,
    this.icon,
    this.people,
    this.color,
    this.nextColor,
  });

  final String title;
  final String time;
  final String people;
  final IconData icon;
  final Color color;
  final Color nextColor;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: nextColor,
      child: Container(
        decoration: BoxDecoration(
          color: color,
          borderRadius: const BorderRadius.only(
            bottomLeft: Radius.circular(80.0),
          ),
        ),
        padding: const EdgeInsets.only(
          left: 32,
          top: 80.0,
          bottom: 50,
        ),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                time,
                style: TextStyle(color: Colors.white, fontSize: 12),
              ),
              const SizedBox(
                height: 2,
              ),
              Text(
                title,
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 22,
                    fontWeight: FontWeight.bold),
              ),
              Row(),
            ]),
      ),
    );
  }
}

Here is the output

Note: I don't claim it to be optimal, but still easy and neat.

Hope that helped!

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

1 Comment

This was an easy and the neat way I could have thinked of, was expecting to learn something new! but yeah Simple works in Flutter! Thanks for keeping it simple.
2

Use Align and set heightFactor: 0.75 and alignment: Alignment.topCenter,

 ListView(
  children: [
    Align(
      heightFactor: 0.75,
      alignment: Alignment.topCenter,
      child: CurvedListItem(
        title: 'Yoga and Meditation for Beginners',
        time: 'TODAY 5:30 PM',
      ),
    ),
    Align(
      heightFactor: 0.75,
      alignment: Alignment.topCenter,
      child: CurvedListItem(
        title: 'Practice French, English And Chinese',
        time: 'TUESDAY 5:30 PM',
      ),
    ),
    Align(
      heightFactor: 0.75,
      alignment: Alignment.topCenter,
      child: CurvedListItem(
        title: 'Adobe XD Live Event in Europe',
        time: 'FRIDAY 6:00 PM',
      ),
    )
  ],
);

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.