现在人们对于网站的美感要求是越来越高了,所以很多布局需要优美的曲线设计。当然最简单的办法是作一个PNG的透明图片,然后外边放一个Container.但其内容如果本身就不是图片,只是容器,这种放入图片的做法会让包体变大。其实我们完全可以使用贝塞尔曲线进行切割。

贝塞尔曲线切割 - 图1

主入口文件main.dart

  1. import 'package:flutter/material.dart';
  2. import 'custom_clipper.dart';
  3. void main() => runApp(MyApp());
  4. class MyApp extends StatelessWidget {
  5. @override
  6. Widget build(BuildContext context) {
  7. return MaterialApp(
  8. title:'Flutter Demo',
  9. debugShowCheckedModeBanner: false,
  10. theme:ThemeData(
  11. primarySwatch: Colors.blue,
  12. ),
  13. home:HomePage()
  14. );
  15. }
  16. }

ClipPath 路径裁切控件

clipPath控件可以把其内部的子控件切割,它有两个主要属性(参数):

  • child :要切割的元素,可以是容器,图片
  • clipper : 切割的路径,这个要和CustomClipper对象配合使用。
  • (new) ClipPath ClipPath({Key key, CustomClipper clipper, Clip clipBehavior = Clip.antiAlias, Widget child})
    1. import 'package:flutter/material.dart';
    2. class HomePage extends StatelessWidget {
    3. @override
    4. Widget build(BuildContext context) {
    5. return Scaffold(
    6. body:Column(
    7. children: <Widget>[
    8. ClipPath(
    9. clipper:BottomClipper(),
    10. child: Container(
    11. color:Colors.deepPurpleAccent,
    12. height: 200.0,
    13. ),
    14. )
    15. ],
    16. )
    17. );
    18. }
    19. }
    在Scaffold里放置了一个列容器,然后把ClipPath控件放到了里边,ClipPath的子元素是一个容器控件Container。BootomClipper是我们自定义的一个对象,里边主要就是切割的路径。

CustomClipper 裁切路径

我们主要的贝塞尔曲线路径就写在getClip方法里,它返回一段路径。
一个二阶的贝塞尔曲线是需要控制点和终点的,控制点就像一块磁铁,把直线吸引过去,形成一个完美的弧度,这个弧度就是贝塞尔曲线了。
我们先来熟悉一下裁切路径和贝塞尔曲线,作一个最简单的贝塞尔曲线出来。
全部代码如下:

  1. import 'package:flutter/material.dart';
  2. class HomePage extends StatelessWidget {
  3. @override
  4. Widget build(BuildContext context) {
  5. return Scaffold(
  6. body:Column(
  7. children: <Widget>[
  8. ClipPath(
  9. clipper:BottomClipperTest(),
  10. child: Container(
  11. color:Colors.deepPurpleAccent,
  12. height: 200.0,
  13. ),
  14. )
  15. ],
  16. )
  17. );
  18. }
  19. }
  20. class BottomClipperTest extends CustomClipper<Path>{
  21. @override
  22. Path getClip(Size size) {
  23. var path = Path();
  24. path.lineTo(0, 0);
  25. path.lineTo(0, size.height-30);
  26. var firstControlPoint =Offset(size.width/2,size.height);
  27. var firstEndPoint = Offset(size.width,size.height-30);
  28. path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstEndPoint.dx, firstEndPoint.dy);
  29. path.lineTo(size.width, size.height-30);
  30. path.lineTo(size.width, 0);
  31. return path;
  32. }
  33. @override
  34. bool shouldReclip(CustomClipper<Path> oldClipper) {
  35. return false;
  36. }
  37. }