You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现如图所示的曲线布局?

在Flutter中实现曲线布局的几种方案

要实现你图中的顶部曲线布局,这里有几种实用的Flutter原生实现方式,按需选择:

方案1:自定义裁剪器(灵活适配任意曲线)

通过ClipPath搭配CustomClipper,可以完全自定义曲线形状,适合需要独特曲线的场景。

示例代码

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          // 顶部曲线区域
          ClipPath(
            clipper: _TopCurveClipper(),
            child: Container(
              height: 220,
              color: Colors.blueAccent,
              alignment: Alignment.center,
              child: const Text(
                "曲线顶部布局",
                style: TextStyle(color: Colors.white, fontSize: 22, fontWeight: FontWeight.w500),
              ),
            ),
          ),
          // 下方内容区
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: const [
                  Text("下方内容", style: TextStyle(fontSize: 18)),
                  SizedBox(height: 10),
                  Text("这是布局下方的普通内容区域"),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}

// 自定义裁剪器实现顶部曲线
class _TopCurveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    // 从左下角开始绘制
    path.lineTo(0, size.height);
    // 二次贝塞尔曲线:调整控制点可改变曲线弧度
    path.quadraticBezierTo(
      size.width / 2,
      size.height - 60,
      size.width,
      size.height,
    );
    // 回到右上角,闭合路径
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

你可以修改quadraticBezierTo的控制点坐标,或者换成cubicTo实现三次贝塞尔曲线,来调整曲线的形状和弧度。

方案2:边框圆角(快速实现简单弧形)

如果只需要对称的底部弧形,不需要复杂曲线,直接用Container的BorderRadius就能快速实现,代码更简洁。

示例代码

Container(
  height: 200,
  decoration: const BoxDecoration(
    color: Colors.green,
    borderRadius: BorderRadius.only(
      bottomLeft: Radius.circular(60),
      bottomRight: Radius.circular(60),
    ),
  ),
  alignment: Alignment.center,
  child: const Text(
    "简单弧形顶部",
    style: TextStyle(color: Colors.white, fontSize: 20),
  ),
)

方案3:自定义绘制(复杂波浪/多曲线场景)

如果需要波浪形或多段曲线的背景,用CustomPainter直接绘制背景路径,再通过Stack叠加内容。

示例代码

class WaveBackgroundPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = Colors.orange;
    final path = Path();
    
    path.lineTo(0, size.height);
    // 多段贝塞尔曲线形成波浪效果
    path.quadraticBezierTo(size.width/4, size.height-40, size.width/2, size.height-15);
    path.quadraticBezierTo(size.width*3/4, size.height+10, size.width, size.height-35);
    path.lineTo(size.width, 0);
    path.close();
    
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

// 使用方式
Stack(
  children: [
    SizedBox(
      height: 220,
      width: double.infinity,
      child: CustomPaint(painter: WaveBackgroundPainter()),
    ),
    const Positioned(
      top: 90,
      left: 0,
      right: 0,
      child: Center(
        child: Text(
          "波浪形曲线背景",
          style: TextStyle(color: Colors.white, fontSize: 22),
        ),
      ),
    )
  ],
)

内容的提问来源于stack exchange,提问作者DL Studio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:32:41