【问题标题】:How to insert custom clip-type containers in Flutter如何在 Flutter 中插入自定义剪辑类型的容器
【发布时间】:2022-08-16 01:40:23
【问题描述】:

我想在我的 Flutter App 中插入一些 Containers。有人可以告诉我,我怎样才能使图像中的containers 中的 1,2 编号?如果有小部件/包,请与我分享它的链接。

    标签: flutter dart


    【解决方案1】:

    下面的代码应该可以解决问题。它使用CustomPaint 小部件来绘制剪辑。

    这是结果(另外,live demo on DartPad):

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(),
          debugShowCheckedModeBanner: false,
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: const Color.fromARGB(255, 245, 245, 245),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: const [
                Padding(
                  padding: EdgeInsets.fromLTRB(30.0, 30.0, 30.0, 0),
                  child: ClipCard(
                    clipText: '1',
                    title: 'Refer',
                    description:
                        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla risus sapien, luctus id dapibus eu, eleifend in turpis.',
                  ),
                ),
                Padding(
                  padding: EdgeInsets.fromLTRB(30.0, 15, 30.0, 0),
                  child: ClipCard(
                    clipText: '2',
                    title: 'Earn',
                    description:
                        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla risus sapien, luctus id dapibus eu, eleifend in turpis.',
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class ClipCard extends StatelessWidget {
      final String clipText;
      final String title;
      final String description;
      const ClipCard({
        Key? key,
        required this.clipText,
        required this.title,
        required this.description,
      }) : super(key: key);
    
      static const clipSize = 45.0;
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            Container(
              width: double.infinity,
              height: 170,
              color: Colors.white,
            ),
            Clip(
              size: clipSize,
              text: clipText,
            ),
            Positioned(
              top: 28,
              left: clipSize,
              child: Text(
                title,
                style: const TextStyle(fontSize: 28, height: 1),
              ),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(28.0, 80.0, 28.0, 28.0),
              child: Text(
                description,
                style: const TextStyle(fontSize: 24),
                overflow: TextOverflow.clip,
              ),
            ),
          ],
        );
      }
    }
    
    class Clip extends StatelessWidget {
      final double size;
      final double topOffset;
      final String text;
      const Clip({
        Key? key,
        required this.size,
        this.topOffset = 20,
        required this.text,
      }) : super(key: key);
    
      static const clipArcRadius = 4.0;
    
      @override
      Widget build(BuildContext context) {
        return Transform.translate(
          offset: Offset(-clipArcRadius, topOffset),
          child: SizedBox(
            width: size,
            height: size,
            child: CustomPaint(
              painter: const ClipPainter(clipArcRadius: clipArcRadius),
              child: Center(
                  child: Transform.translate(
                offset: const Offset(-clipArcRadius, -clipArcRadius / 2),
                child: Text(
                  text,
                  style: TextStyle(
                      color: Colors.white, fontSize: size * 0.6, height: 1),
                ),
              )),
            ),
          ),
        );
      }
    }
    
    class ClipPainter extends CustomPainter {
      final double clipArcRadius;
    
      const ClipPainter({this.clipArcRadius = 4});
    
      @override
      void paint(Canvas canvas, Size size) {
        final paint = Paint()
          ..color = const Color.fromARGB(255, 79, 79, 79)
          ..style = PaintingStyle.fill;
    
        final path = Path()
          ..lineTo(0, size.height - 8)
          ..arcTo(
              Rect.fromLTWH(
                0,
                size.height - clipArcRadius * 2,
                clipArcRadius * 2,
                clipArcRadius * 2,
              ),
              pi,
              -pi / 2,
              false)
          ..lineTo(clipArcRadius, size.height - clipArcRadius)
          ..lineTo(size.width - 8, size.height - clipArcRadius)
          ..lineTo(size.width - 8, (size.height - clipArcRadius) / 2 - 6)
          ..lineTo(size.width, (size.height - clipArcRadius) / 2)
          ..lineTo(size.width - 8, (size.height - clipArcRadius) / 2 + 6)
          ..lineTo(size.width - 8, 0)
          ..close();
    
        canvas.drawPath(path, paint);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-04
      • 2020-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-03
      • 2021-01-20
      相关资源
      最近更新 更多