如何在颤抖中创建这曲线?

发布于 2025-02-09 14:58:22 字数 191 浏览 1 评论 0原文

如何使用颤动创建此曲线和两个彩色顶部的“ Appbar”?

How Can I create this curves and two coloured top "appBar" using Flutter?
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黑寡妇 2025-02-16 14:58:22

自定义窗口小部件将可以解决问题。有了它,可以像您要​​的那样在背景中绘制自定义形状。这只是使用 stack widget 然后上方的其他小部件。

这是登录屏幕的原型:

”在此处输入图像描述”

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

const loginMainColor = Color.fromARGB(255, 67, 123, 122);
const loginOtherColor = Color.fromARGB(255, 253, 236, 229);

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Shape Widget Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const LoginPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final width = MediaQuery.of(context).size.width;
    final height = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: loginMainColor,
      ),
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Stack(
            children: [
              CustomPaint(
                size: Size(width, height),
                painter: const BackgroundPainter(90),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 16, right: 16),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: const [
                    Text(
                      'Log in',
                      style: TextStyle(
                          fontSize: 30,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 60 - 16),
                      child: Text(
                        'Lorem ipsum dolor sit amet',
                        style: TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.bold,
                            color: Colors.white),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 30),
                      child: TextField(
                        decoration: InputDecoration(
                          label: Text('Email'),
                          floatingLabelBehavior: FloatingLabelBehavior.always,
                        ),
                      ),
                    ),
                    TextField(
                      decoration: InputDecoration(
                        label: Text('Password'),
                        floatingLabelBehavior: FloatingLabelBehavior.always,
                      ),
                    )
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class BackgroundPainter extends CustomPainter {
  final double titleBarHeight;
  const BackgroundPainter(this.titleBarHeight);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()..color = loginMainColor;

    const smallRadius = 50.0;
    const bigRadius = 120.0;

    canvas.drawCircle(
        Offset(smallRadius, titleBarHeight - smallRadius), smallRadius, paint);
    canvas.drawRect(
      Rect.fromPoints(
        Offset(0, 0),
        Offset(size.width, titleBarHeight - smallRadius),
      ),
      paint,
    );
    canvas.drawRect(
      Rect.fromPoints(
        Offset(smallRadius, titleBarHeight - smallRadius),
        Offset(size.width, titleBarHeight),
      ),
      paint,
    );

    paint.color = loginOtherColor;
    canvas.drawCircle(
        Offset(size.width, titleBarHeight + 60), bigRadius, paint);

    paint.color = Colors.white;
    canvas.drawCircle(
        Offset(size.width - smallRadius, titleBarHeight + smallRadius),
        smallRadius,
        paint);
    canvas.drawRect(
        Rect.fromPoints(
          Offset(size.width - bigRadius, titleBarHeight),
          Offset(size.width - smallRadius, titleBarHeight + 60 + bigRadius),
        ),
        paint);
    canvas.drawRect(
        Rect.fromPoints(
          Offset(size.width - smallRadius, titleBarHeight + smallRadius),
          Offset(size.width, titleBarHeight + 60 + bigRadius),
        ),
        paint);
  }

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

The CustomPaint widget will do the trick. With it, it's possible to paint custom shapes in the background like the one you asked for. It's just a matter of using the Stack widget to paint the background first and then the other widgets above it.

This is a prototype of the login screen:

enter image description here

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

const loginMainColor = Color.fromARGB(255, 67, 123, 122);
const loginOtherColor = Color.fromARGB(255, 253, 236, 229);

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Shape Widget Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const LoginPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final width = MediaQuery.of(context).size.width;
    final height = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: loginMainColor,
      ),
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Stack(
            children: [
              CustomPaint(
                size: Size(width, height),
                painter: const BackgroundPainter(90),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 16, right: 16),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: const [
                    Text(
                      'Log in',
                      style: TextStyle(
                          fontSize: 30,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 60 - 16),
                      child: Text(
                        'Lorem ipsum dolor sit amet',
                        style: TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.bold,
                            color: Colors.white),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.only(bottom: 30),
                      child: TextField(
                        decoration: InputDecoration(
                          label: Text('Email'),
                          floatingLabelBehavior: FloatingLabelBehavior.always,
                        ),
                      ),
                    ),
                    TextField(
                      decoration: InputDecoration(
                        label: Text('Password'),
                        floatingLabelBehavior: FloatingLabelBehavior.always,
                      ),
                    )
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class BackgroundPainter extends CustomPainter {
  final double titleBarHeight;
  const BackgroundPainter(this.titleBarHeight);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()..color = loginMainColor;

    const smallRadius = 50.0;
    const bigRadius = 120.0;

    canvas.drawCircle(
        Offset(smallRadius, titleBarHeight - smallRadius), smallRadius, paint);
    canvas.drawRect(
      Rect.fromPoints(
        Offset(0, 0),
        Offset(size.width, titleBarHeight - smallRadius),
      ),
      paint,
    );
    canvas.drawRect(
      Rect.fromPoints(
        Offset(smallRadius, titleBarHeight - smallRadius),
        Offset(size.width, titleBarHeight),
      ),
      paint,
    );

    paint.color = loginOtherColor;
    canvas.drawCircle(
        Offset(size.width, titleBarHeight + 60), bigRadius, paint);

    paint.color = Colors.white;
    canvas.drawCircle(
        Offset(size.width - smallRadius, titleBarHeight + smallRadius),
        smallRadius,
        paint);
    canvas.drawRect(
        Rect.fromPoints(
          Offset(size.width - bigRadius, titleBarHeight),
          Offset(size.width - smallRadius, titleBarHeight + 60 + bigRadius),
        ),
        paint);
    canvas.drawRect(
        Rect.fromPoints(
          Offset(size.width - smallRadius, titleBarHeight + smallRadius),
          Offset(size.width, titleBarHeight + 60 + bigRadius),
        ),
        paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}
拥醉 2025-02-16 14:58:22

正如Lepsch评论的那样,CustomPaint是必经之路,但是您发现它很复杂或耗时,您还可以从诸如fluttershapemaker之类的工具中获得一些帮助( fluttershapemaker ),它使您可以像在某些设计软件中一样绘制形状,然后将它们导出到ustompainter

首先,按照自己的意愿编辑形状

然后您导出它,该工具生成所需的类和导入

As lepsch commented, CustomPaint is the way to go, but it you find it complicated or time-consuming, you can also get some help from tools such as FlutterShapeMaker (FlutterShapeMaker), which allows you to draw your shapes as if you were in some design software and export them into a CustomPainter class

First you edit your shape as you like
enter image description here

Then you export it and the tool generates the required class and imports
enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文