簡體   English   中英

應用欄上的圓形底部

[英]Rounded bottom on appbar

我想制作一個底部圓潤的應用欄,如下所示:

圓形應用欄

我將如何實施這樣的應用欄? 我曾嘗試閱讀 CustomPainter 的文檔,但我覺得這不是要走的路。

在 Flutter 中,您可以在 AppBar 小部件中使用 shape 屬性自定義形狀。

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

您可以使用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)),
    ),
  ),

在此處輸入圖片說明

雖然您可能會注意到:這不是完美的像素。 邊框不是一個實際的圓,而是一個省略號。 這可能是不受歡迎的。

一種更現實但更復雜的方法是繪制一個半徑基於屏幕寬度的圓。 這將溢出容器。 然后剪輯一下。

你需要一些東西: 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);
}

故意居中,只是為了展示剪輯的工作原理在此處輸入圖片說明

使用 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, ), ),

現在創建一個像 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;
 }
}

改變你的身高分數,我保留了 heights-50 以獲得你想要的漂亮曲線

輸出如下 -

在此處輸入圖片說明

您的上述幫助了我很多,我只是在為一件事而苦苦掙扎,那就是使圓條的高度小很多。

我改變了這一行的高度

 Size get preferredSize => const Size.fromHeight(200.0);

但這對它的影響還不夠,我什至將其設置為 0,但標准仍然很高。

您可以通過以下方式獲得確切的輸出:

AppBar(
    toolbarHeight:MediaQuery.of(context).size.height/4,
    leading: Container(),
    shape: RoundedRectangleBorder(
      borderRadius: new BorderRadius.vertical(
        bottom: new Radius.elliptical(SizeConfig.screenWidth, 56.0),
      ),
    ),
  ),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM