android - 想要在 CustomClipper 上添加高程仅边界而不是下方的整个材料
问题描述
我正在尝试通过使用材质的高程在自定义路径上添加高程,但看起来没有做任何事情,我尝试了其他方法但在整个材质(矩形)上获得了高程。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.pink[300],
body: Column(
children: <Widget>[
TopContainer(),
],
));
}
}
class TopContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ClipPath(
clipper: ImageClipper(),
child: Material(
elevation: 15.0,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://images.pexels.com/photos/3309467/pexels-photo-3309467.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
),
),
),
constraints: BoxConstraints.expand(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.5,
),
),
));
}
}
class ImageClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
var path = Path();
path.lineTo(0.0, size.height);
var firstControlPoint = Offset(size.width * 0.35, size.height * 0.75);
var firstEndPoint = Offset(size.width * 0.65, size.height * 0.85);
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstEndPoint.dx, firstEndPoint.dy);
///////////////////////////////////////////////
var secondControlPoint = Offset(size.width * 0.85, size.height * 0.90);
var secondEndPoint = Offset(size.width, size.height * 0.75);
path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
secondEndPoint.dx, secondEndPoint.dy);
// path.lineTo(size.width, size.height * 0.9);
path.lineTo(size.width, 0.0);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
我正在尝试通过使用材质的高程在自定义路径上添加高程,但看起来没有做任何事情,我尝试了其他方法但在整个材质(矩形)上获得了高程。
解决方案
使用那个习惯ShapeBorder
class WaveShapeBorder extends ShapeBorder {
@override EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override ui.Path getInnerPath(ui.Rect rect, {ui.TextDirection textDirection}) => null;
@override
ui.Path getOuterPath(ui.Rect rect, {ui.TextDirection textDirection}) {
var ctrl1 = FractionalOffset(0.35, 0.75).withinRect(rect);
var end1 = FractionalOffset(0.65, 0.85).withinRect(rect);
var ctrl2 = FractionalOffset(0.85, 0.90).withinRect(rect);
var end2 = FractionalOffset(1.0, 0.75).withinRect(rect);
return Path()
..moveTo(rect.topLeft.dx, rect.topLeft.dy)
..lineTo(rect.bottomLeft.dx, rect.bottomLeft.dy)
..quadraticBezierTo(ctrl1.dx, ctrl1.dy, end1.dx, end1.dy)
..quadraticBezierTo(ctrl2.dx, ctrl2.dy, end2.dx, end2.dy)
..lineTo(rect.topRight.dx, rect.topRight.dy)
..close();
}
@override void paint(ui.Canvas canvas, ui.Rect rect, {ui.TextDirection textDirection}) {}
@override ShapeBorder scale(double t) => this;
}
和这个用于测试的示例代码:
class WaveShapeBorderTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.teal, Colors.green],
begin: Alignment.topRight,
end: Alignment.centerLeft,
),
),
child: Stack(
children: [
Material(
elevation: 6,
shape: WaveShapeBorder(),
clipBehavior: Clip.antiAlias,
child: Image.asset('images/someImage.png'),
),
],
),
);
}
}
当然,您可以自由使用它,但主要思想是使用Material.shape
和Material.clipBehavior
属性
这是最终结果:
编辑,如果你认为你的阴影太“轻”,你可以添加一个额外Container
的自定义阴影:
class WaveShapeBorderTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.teal, Colors.green],
begin: Alignment.topRight,
end: Alignment.centerLeft,
),
),
child: Stack(
children: [
Container(
decoration: ShapeDecoration(
shape: WaveShapeBorder(),
shadows: [
BoxShadow(color: Colors.black, blurRadius: 16, offset: Offset(2, 2), spreadRadius: 8),
]
),
child: Material(
clipBehavior: Clip.antiAlias,
shape: WaveShapeBorder(),
child: Image.asset('images/someImage.png',),
),
),
Icon(Icons.photo, size: 64,),
],
),
);
}
}
你会看到这个:
推荐阅读
- python - 是什么阻止计算机向我的程序输出解决方案?
- python-3.x - 将python函数作为arg传递给PyQt5中的函数
- excel - 如何消除以文本开头并具有文本和数字的单元格中的前导零
- asp.net - 我可以将模型类中的 json 对象发布到角度 .ts 文件吗
- mysql - dolphindb在插入数据时如何指定像MySQL这样的列名?
- nativescript - Nativescript 6.2 - 将 base64 图像字符串转换为 imageSource
- php - Laravel 外键迁移
- python - 得到一个错误,说'self.mydictValues'没有定义,只得到那个函数中的错误(在其他人中使用并且完美地工作)
- linux - 我可以在 Trace Compass 中同时查看 LTTng 跟踪的用户空间事件和内核事件吗?
- java - 在 Java 中检测到异常时如何重复代码?