[英]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,
),
),
],
),
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.