简体   繁体   English

Flutter 如何在使用自定义滚动视图时(或内部)显示自定义剪辑器

[英]Flutter how to display a Custom Clipper when (or inside) using a Custom Scroll View

so here's the deal.所以这是交易。 I created (sort of) a custom clipper shaped like a wave inside a class called WaveClipper我在 class 中创建了(某种程度上)形状像波浪的自定义剪辑器,称为 WaveClipper

the wave clipper class:波剪 class:

class WaveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0, 220);
    path.quadraticBezierTo(size.width / 4, 160 , size.width / 2, 175);
    path.quadraticBezierTo(3 / 4 * size.width, 190, size.width, 130);
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

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

And whenever I display it using a scaffold it shows fine however when I try to push it inside a SliverListView which is inside a CustomScrollView then nothing appears and there are no errors either.每当我使用脚手架显示它时,它都显示正常,但是当我尝试将它推入 CustomScrollView 内的 SliverListView 时,什么也没有出现,也没有错误。 Is the clipper under the content?剪辑器在内容下方吗? And how can I display it.我该如何显示它。

the clipper I am trying to show:我要展示的快船:

         Stack(
            children: [
              ClipPath(
                  clipper: WaveClipper(),
                  child: Container(
                    color: Colors.cyanAccent,
                  ))
               ],
             ),

where I am trying to show it:我试图展示它的地方:

Scaffold(
  appBar: AppBar(
    backgroundColor: Colors.white,
    elevation: 0.0,
    iconTheme: IconThemeData(
      color: Colors.cyanAccent,
    ),
  ),
  backgroundColor: Colors.white,
  body: CustomScrollView(
    physics: const BouncingScrollPhysics(),
    slivers: [
      SliverList(
        delegate: SliverChildListDelegate([
          //here 
          //there rest of the content (mostly buttons)
        ]),
      ),
    ],
  ),
)

Any help is appreciated and thank you for taking the time.感谢您提供任何帮助,感谢您抽出宝贵时间。

Try to give some dimension to your Container :尝试为您的Container提供一些维度:

在此处输入图像描述

Stack(
  children: [
    ClipPath(
      clipper: WaveClipper(),
      child: Container(
        height: 300,
        color: Colors.amber.shade200,
      ),
    ),
  ],
),

Full source code完整的源代码

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0.0,
        iconTheme: IconThemeData(
          color: Colors.cyanAccent,
        ),
      ),
      backgroundColor: Colors.white,
      body: CustomScrollView(
        physics: const BouncingScrollPhysics(),
        slivers: [
          SliverList(
            delegate: SliverChildListDelegate([
              Stack(
                children: [
                  ClipPath(
                    clipper: WaveClipper(),
                    child: Container(
                      height: 300,
                      color: Colors.amber.shade200,
                    ),
                  ),
                ],
              ),
            ]),
          ),
        ],
      ),
    );
  }
}

class WaveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0, 220);
    path.quadraticBezierTo(size.width / 4, 160, size.width / 2, 175);
    path.quadraticBezierTo(3 / 4 * size.width, 190, size.width, 130);
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}
        Container(
            height: device.size.height * 0.3,
            child: Scaffold(
              body: Stack(
                clipBehavior: Clip.none,
                children: [
                  ClipPath(
                      clipper: WaveClipper(),
                      child: Container(
                        color: Colors.cyanAccent,
                      ))
                ],
              ),
            ),
          ),

Wrap with a Scaffold and give that Scaffold a size using a Container, if anyone has a better solution by all means post it.如果有人有更好的解决方案,请用 Scaffold 包裹并使用 Container 为 Scaffold 指定尺寸。

import 'package:flutter/material.dart';

class LoginScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
   return Scaffold(
     body: Container(
       child: Stack(
         children: [
           Opacity(opacity: 0.5,
           child: ClipPath(
             clipper: WaveClipper(),
             child: Container(color: Colors.red,
             height: 200,),
           ),
           ),
           ClipPath(
             clipper: WaveClipper(),
             child: Container(color: Colors.deepOrange,
             height: 180,),
           ),
         ],
       ),
     ),
   );
  }
}

class WaveClipper extends CustomClipper<Path>{
  @override
  Path getClip(Size size){
    debugPrint(size.width.toString());
    var path = new Path();
    path.lineTo(0,size.height);
    var firstStart = Offset(size.width / 5,size.height);
    var firstEnd = Offset(size.width / 2.25,size.height - 50);
     path.quadraticBezierTo(firstStart.dx, firstStart.dy, firstEnd.dx, firstEnd.dy);

 var secondStart = Offset(size.width -(size.width/3.24), size.height - 105);
    var secondEnd = Offset(size.width, size.height - 10);
    path.quadraticBezierTo(secondStart.dx, secondStart.dy, secondEnd.dx, secondEnd.dy);

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

  }

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

Optionally add dotted_decoration package if needed: https://pub.dev/packages/dotted_decoration如果需要,可以选择添加dotted_decoration package: https://pub.dev/packages/dotted_decoration

在此处输入图像描述

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: DiscountTile()),
    );
  }
}

class DiscountTile extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipPath(
      clipper: _DiscountTileClipper(),
      child: Container(
        clipBehavior: Clip.antiAlias,
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(16)),
        ),
        child: ColoredBox(
          color: Colors.blue,
          child: Row(
            children: [
              SizedBox(width: 100),
              Expanded(
                child: DecoratedBox(
                  decoration: DottedDecoration(
                    linePosition: LinePosition.left,
                    color: Colors.red,
                    strokeWidth: 3,
                  ),
                  child: Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Text('hello world' * 20),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _DiscountTileClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    const Radius radius = Radius.circular(1);
    const bool clockwise = false;
    const double clipRadius = 20;
    const double decreaseValueWidgetWidth = 100.0;
    const double leftPadding = decreaseValueWidgetWidth + 9;

    return Path()
      ..lineTo(leftPadding - clipRadius, 0)
      ..arcToPoint(
        const Offset(leftPadding, 0),
        clockwise: clockwise,
        radius: radius,
      )
      ..lineTo(size.width, 0)
      ..lineTo(size.width, size.height)
      ..lineTo(leftPadding, size.height)
      ..arcToPoint(
        Offset(leftPadding - clipRadius, size.height),
        clockwise: clockwise,
        radius: radius,
      )
      ..lineTo(0, size.height)
      ..close();
  }

  @override
  bool shouldReclip(_DiscountTileClipper oldClipper) => true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM