Home > other >  make curve/ concave like below image with container in flutter?
make curve/ concave like below image with container in flutter?

Time:02-15

I'm familier with ClipPath widget , but help of this I can only make corner round or border round and circle. I know this will fixed by ClipPath or CustomPainter widget. but don't know to how to do.

Expected image:

enter image description here

Actual result :

enter image description here

CODE:


import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SampleExample(),
    );
  }
}

  class SampleExample extends StatelessWidget {
    const SampleExample({ Key? key }) : super(key: key);

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        backgroundColor: Colors.red,
        body:  Container(
          alignment: Alignment.bottomCenter,
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          child: Container(

              height: 250.0,
              decoration:  BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.vertical(
                  top: Radius.elliptical(
                        MediaQuery.of(context).size.width, 120.0)),
                  
              ),
            ),
        ),
        
      );
    }
  }

CodePudding user response:

One way you can do this is like so using CustomPainter.

class SampleExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      backgroundColor: Colors.red,
      body: Align(
        alignment: Alignment.bottomCenter,
        child: CustomPaint(
          painter: MyCustomPainter(),
          child: SizedBox(
            width: double.infinity,
            height: 250,
            child: Center(child: Text('Cool!')),
          ),
        ),
      ),
    );
  }
}

class MyCustomPainter extends CustomPainter {
  const MyCustomPainter();

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;

    final path = Path()
      ..moveTo(0, 0)
      ..quadraticBezierTo(size.width / 2, size.height / 4, size.width, 0)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..close();

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

enter image description here

CodePudding user response:

By using Stack widget, I implemented what you want layout.

  • Draw white background
  • Stacked bottom elliptical red Rect widget

enter image description here

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SampleExample(),
    );
  }
}

class SampleExample extends StatelessWidget {
  const SampleExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Container(
            height: 250.0,
            decoration: BoxDecoration(
              color: Colors.red,
              borderRadius: BorderRadius.vertical(
                  bottom: Radius.elliptical(
                      MediaQuery.of(context).size.width, 120.0)),
            ),
          ),
        ],
      ),
    );
  }
}


CodePudding user response:

On decoration>borderRadius replace top with bottom and use alignment: Alignment.topCenter instead of bottomCenter on body Container.

body: Container(
  alignment: Alignment.topCenter,
  height: MediaQuery.of(context).size.height,
  width: MediaQuery.of(context).size.width,
  child: Container(
    height: 250.0,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.vertical(
          bottom: Radius.elliptical(
              MediaQuery.of(context).size.width, 120.0)),
    ),
  ),
),

CodePudding user response:

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: ClipPath(
              clipper: CurveClipper(),
              child: Container(
                color: Colors.lightGreen,
                height: 250.0,
                child: Center(
                    child: Padding(
                      padding: EdgeInsets.only(bottom: 50),
                      child: Text(
                        "Curved View",
                        style: TextStyle(
                          fontSize: 25,
                          color: Colors.white,
                        ),
                      ),
                    )),
              ),
            ),
          ),
        );
      }
    }  

 


 class CurveClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        int curveHeight = 40;
        Offset controlPoint = Offset(size.width / 2, size.height   curveHeight);
        Offset endPoint = Offset(size.width, size.height - curveHeight);
    
        Path path = Path()
          ..lineTo(0, size.height - curveHeight)
          ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, endPoint.dx, endPoint.dy)
          ..lineTo(size.width, 0)
          ..close();
    
        return path;
      }
    
      @override
      bool shouldReclip(CustomClipper<Path> oldClipper) => false;
    }
  • Related