appbar上的圆形底部

Mik*_*ika 2 dart flutter

我想制作一个圆底的appbar,如下所示:

圆形的appbar

我将如何实现这样的appbar?我试过阅读CustomPainter的文档,但我觉得这不是那样的.

Abd*_*pal 63

在 Flutter 中,您可以在 AppBar 小部件中使用 shape 属性自定义形状。

  AppBar(
    title: Text('My App'),
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(
        bottom: Radius.circular(30),
      ),
    ),
  ),
Run Code Online (Sandbox Code Playgroud)


Rém*_*let 8

您可以使用BoxDecoration到边界半径和阴影添加到Container/ DecoratedBox.

 new Container(
    height: 200.0,
    decoration: new BoxDecoration(
      color: Colors.orange,
      boxShadow: [
        new BoxShadow(blurRadius: 40.0)
      ],
      borderRadius: new BorderRadius.vertical(
          bottom: new Radius.elliptical(
              MediaQuery.of(context).size.width, 100.0)),
    ),
  ),
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

虽然您可能会注意到:这不是完美的像素.边框不是实际的圆圈,而是省略号.这可能是不受欢迎的.

更现实但更复杂的方法是根据屏幕宽度绘制一个半径为圆的圆.哪个会溢出容器.然后剪辑它.

你需要一些东西:LayoutBuilder,以获得宽度.ClipRect不要在容器的约束之外绘画.并且OverflowBox,布局一个比它的父级更大的圆.

class RoundedAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Widget build(BuildContext context) {
    return new SizedBox.fromSize(
      size: preferredSize,
      child: new LayoutBuilder(builder: (context, constraint) {
        final width = constraint.maxWidth * 8;
        return new ClipRect(
          child: new OverflowBox(
            maxHeight: double.infinity,
            maxWidth: double.infinity,
            child: new SizedBox(
              width: width,
              height: width,
              child: new Padding(
                padding: new EdgeInsets.only(
                  bottom: width / 2 - preferredSize.height / 2),                    
                child: new DecoratedBox(
                  decoration: new BoxDecoration(
                    color: Colors.orange,
                    shape: BoxShape.circle,
                    boxShadow: [
                      new BoxShadow(color: Colors.black54, blurRadius: 10.0)
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }),
    );
  }

  @override
  Size get preferredSize => const Size.fromHeight(200.0);
}
Run Code Online (Sandbox Code Playgroud)

故意居中,只是为了展示剪辑是如何工作的在此输入图像描述


min*_*eek 5

使用 ClipPath 有一种简单的方法可以实现此目的 -

  1. 将背景颜色应用于 AppBar

  2. 在正文中的 AppBar 正下方创建一个具有一定高度(例如 240)的 SizedBox/Container,并应用相同的背景颜色

  3. 使用 ClipPath 小部件来包装该 SizedBox/Container

       ClipPath(
       clipper: CustomShape(), // this is my own class which extendsCustomClipper
       child: Container(
       height: 150,
       color: kPrimaryColor,
       ),
     ),
    
    Run Code Online (Sandbox Code Playgroud)

现在创建一个像 CustomShape 这样的类,它扩展了 CustomClipper,如下所示

class CustomShape extends CustomClipper<Path> {
  @override
  getClip(Size size) {
    double height = size.height;
    double width = size.width;
    var path = Path();
    path.lineTo(0, height - 50);
    path.quadraticBezierTo(width / 2, height, width, height - 50);
    path.lineTo(width, 0);
    path.close();
    
    return path;
 }

  @override
    bool shouldReclip(CustomClipper oldClipper) {
    return true;
 }
}
Run Code Online (Sandbox Code Playgroud)

更改你的身高分数,我将高度保留为 50,以获得你想要的漂亮曲线

输出如下 -

在此输入图像描述