颤振:达到Sliverappbar形状

时间:2019-12-29 10:38:04

标签: flutter dart

我在Dribble https://dribbble.com/shots/9175650-Beauty-Salon-App/attachments/1218583?mode=media中发现了一些Appbar设计,我试图像这样创建相同的东西,但是我困惑于彼此获得边界半径。

无背景的试验1:

具有脚手架背景色蓝色的试用版2

试验3的背景色为深橙色

如何实现像链接一样的appbar设计?

源代码

import 'package:flutter/material.dart';
import 'package:flutter_iconpicker/flutter_iconpicker.dart';

class TestingScreen extends StatelessWidget {
  static const routeName = "/testing-screen";
  @override
  Widget build(BuildContext context) {
    var mediaQuery = MediaQuery.of(context);

    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            expandedHeight: mediaQuery.size.height / 4,
            backgroundColor: Colors.deepOrange,
            shape: RoundedRectangleBorder(
                borderRadius:
                    BorderRadius.only(bottomRight: Radius.circular(80))),
          ),
          SliverList(
            delegate: SliverChildListDelegate(
              [
                Container(
                  height: mediaQuery.size.height,
                  decoration: BoxDecoration(
                      color: Colors.blue,
                      borderRadius:
                          BorderRadius.only(topLeft: Radius.circular(80))),
                  child: Center(child: Text('data')),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:1)

您实际上可以使用; Path的方法来使用CustomClipper来做到这一点:

quadraticBezierTo

请注意,我只向第一个小部件添加了曲线。如果要在class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Stack( children: <Widget>[ Container(color: Colors.orange), ClipPath( clipper: TheCustomClipper(), child: Container( color: Colors.greenAccent, ), ), ], ), ), ); } } class TheCustomClipper extends CustomClipper<Path> { @override getClip(Size size) { var path = Path(); path.lineTo(0, size.height / 3); var firstControlPoint = Offset(0, size.height / 3.5); // adjust the height to move start of the first curve var firstEndPoint = Offset(size.width / 4.2, size.height / 3.5 + 10); // adjust the width to add the end controll point and height to move end of the first curve var secControlPoint = Offset(size.width, size.height / 2.8); // adjust the height to move end of the second curve var secEndPoint = Offset(size.width, size.height / 3 - 40); // adjust the width to add the right first controll point and height to move start of the second curve path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstEndPoint.dx, firstEndPoint.dy); path.quadraticBezierTo( secControlPoint.dx, secControlPoint.dy, secEndPoint.dx, secEndPoint.dy); path.lineTo(size.width, size.height / 3); path.lineTo(size.width, 0); path.close(); return path; } @override bool shouldReclip(CustomClipper oldClipper) { return null; } } 的第一个CustomClipper中添加另一个Container,请按照相反的逻辑进行操作。

输出:

enter image description here

答案 1 :(得分:0)

源代码:

import 'package:flutter/material.dart';

import '../../../shared/app_colors.dart';

class WelcomenPage extends StatelessWidget {
  static const id = 'welcomen_page';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: <Widget>[
          ClipPath(
            child: Container(
              height: MediaQuery.of(context).size.height,
              color: AppColors.primary,
            ),
            clipper: BottomWaveClipper(),
          ),
        ],
      ),
    );
  }
}

class BottomWaveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0, size.height * .65);

    var firstControlPoint = Offset(0, size.height * .75);
    var firstEndPoint = Offset(size.width / 6, size.height * .75);

    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstEndPoint.dx, firstEndPoint.dy);

    path.lineTo(size.width / 1.2, size.height * .75);

    var secControlPoint = Offset(size.width, size.height * .75);
    var secEndPoint = Offset(size.width, size.height * 0.85);

    path.quadraticBezierTo(
        secControlPoint.dx, secControlPoint.dy, secEndPoint.dx, secEndPoint.dy);

    path.lineTo(size.width, 0);
    path.close();

    return path;
  }

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

输出: image