如何在Flutter中使容器边界与图像一样?

xmjla07d  于 2023-05-19  发布在  Flutter
关注(0)|答案(1)|浏览(123)

Figma Web Site Design
我想使这个边界,我已经尝试了所有的解决方案stackoverflow。

在这个解决方案中,当我添加borderRadius或当我给边框透明颜色到顶部边框时,边框不显示。
其他一些解决方案正在使用Paint widget,因为:

这是我的代码:

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final description =
      'Lorem ipsum dolor sit amet consectetur. Sed auctor dignissim sit egestas dolor turpis. Nunc congue vulputate tincidunt purus. Non lacus metus tortor elit mauris proin.';

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return SingleChildScrollView(
      child: Column(
        children: [
          FittedBox(
              child: topSection(header: headerWidget(), body: bodyWidget())),
          const SizedBox(height: 20),
          //midSection(),
          CustomTitleWidget(
              height: 200,
              width: double.infinity,
              title: 'Some of my Projects',
              radius: 20,
          ),
        ],
      ),
    );
  }

}

和那些组件绘制我的边界容器和它不像我想要的工作:(输出图像在下方)

class CustomDraw extends CustomPainter {
  late Paint painter;
  late double radius;
  late double textWidth;

  CustomDraw(Color color, this.textWidth, {this.radius = 0}) {
    painter = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2
      ..color = color;
  }

  @override
  void paint(Canvas canvas, Size size) {
    var path = Path();

    path.moveTo(size.width - ((size.width - textWidth) / 2), 0);

    path.lineTo(size.width - radius, 0);
    path.cubicTo(size.width - radius, 0, size.width, 0, size.width, radius);
    path.lineTo(size.width, size.height - radius);
    path.cubicTo(size.width, size.height - radius, size.width, size.height,
        size.width - radius, size.height);

    path.lineTo(radius, size.height);
    path.cubicTo(radius, size.height, 0, size.height, 0, size.height - radius);

    path.lineTo(0, radius);
    path.cubicTo(0, radius, 0, 0, radius, 0);
    path.lineTo(((size.width - textWidth) / 2), 0);

    canvas.drawPath(path, painter);
  }

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

class CustomTitleWidget extends StatefulWidget {
  final double height;
  final double width;
  final double? radius;
  final String title;
  const CustomTitleWidget(
      {Key? key,
        required this.height,
        required this.width,
        required this.title,
        this.radius})
      : super(key: key);

  @override
  State<CustomTitleWidget> createState() => _CustomTitleWidgetState();
}

class _CustomTitleWidgetState extends State<CustomTitleWidget> {
  GlobalKey textKey = GlobalKey();
  double textHeight = 0.0;
  double textWidth = 0.0;

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() {
        final textKeyContext = textKey.currentContext;
        if (textKeyContext != null) {
          final box = textKeyContext.findRenderObject() as RenderBox;
          textHeight = box.size.height;
          textWidth = box.size.width;
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      clipBehavior: Clip.none,
      alignment: Alignment.topCenter,
      children: [
        CustomPaint(
          painter: CustomDraw(
            Colors.black,
            textWidth,
            radius: widget.radius ?? 0,
          ),
          child: SizedBox(
            height: widget.height,
            width: widget.width,
          ),
        ),
        Positioned(
          top: -textHeight / 2,
          left: 60,
          child: Padding(
            key: textKey,
            padding: EdgeInsets.symmetric(horizontal: 8.0),
            child: Container(
              color: Colors.transparent,
              padding: const EdgeInsets.symmetric(horizontal: 10),
              child: Text(
                widget.title,
                style: AppTextStyles.nameTitle,
              ),
            ),
          ),
        )
      ],
    );
  }
}

OUTPUT image

wkyowqbh

wkyowqbh1#

https://youtu.be/3ZrKV8t5mWUg您可以看到组件的最后一个视图
伙计们,谢谢你们不帮忙,但我用这段代码解决了问题:

**如果标题不在中心,您可以更改“位置”小部件的顶部和底部

Stack(
            children: <Widget>[
              Container(
                width: double.infinity,
                margin: const EdgeInsets.fromLTRB(0, 20, 20, 10),
                padding: const EdgeInsets.all(30),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2),
                  borderRadius: const BorderRadius.only(
                    topRight: Radius.circular(20),
                    bottomRight: Radius.circular(20),
                  ),
                  shape: BoxShape.rectangle,
                  color: AppColors.lightGrey4,
                ),
                child: SingleChildScrollView(
                  child: GridView.count(
                    crossAxisCount: 2,
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    children: List.generate(6, (index) {
                      return Container(
                        margin: EdgeInsets.all(10),
                        color: Colors.blue,
                        child: Center(
                          child: Text(
                            'Item ${index + 1}',
                            style: TextStyle(color: Colors.white, fontSize: 16),
                          ),
                        ),
                      );
                    }),
                  ),
                ),
              ),
              Positioned(
                left: 50,
                top: 0,
                child: Container(
                  padding:
                      const EdgeInsets.only(bottom: 10, left: 10, right: 10),
                  decoration: const BoxDecoration(
                    gradient: LinearGradient(
                      colors: [AppColors.mainBackground, AppColors.lightGrey4],
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      stops: [0.5, 0.5],
                    ),
                  ),
                  child: const Text(
                    'Some of My Projects',
                    style: AppTextStyles.nameTitle,
                  ),
                ),
              ),
            ],
          )

相关问题