Flutter 颤振-克利帕斯
如何创建上述自定义clipPath小部件?(我附上了截图) 我试过了,但输出不准确 克利伯级Flutter 颤振-克利帕斯,flutter,dart,Flutter,Dart,如何创建上述自定义clipPath小部件?(我附上了截图) 我试过了,但输出不准确 克利伯级 class MessageClipper extends CustomClipper<Path> { final double borderRadius = 15; @override Path getClip(Size size) { double width = size.width; double height = size.height; doub
class MessageClipper extends CustomClipper<Path> {
final double borderRadius = 15;
@override
Path getClip(Size size) {
double width = size.width;
double height = size.height;
double rheight = height - height / 3;
double oneThird = width / 3;
final path = Path()
..lineTo(0, rheight - borderRadius)
..cubicTo(0, rheight - borderRadius, 0, rheight, borderRadius, rheight)
..lineTo(oneThird, rheight)
..lineTo(width/2-borderRadius, height-borderRadius)
..cubicTo(width / 2 - borderRadius, height - borderRadius, width / 2,
height, width / 2 + borderRadius, height - borderRadius )
..lineTo(2 * oneThird, rheight)
..lineTo(width-borderRadius, rheight)
..cubicTo(width - borderRadius, rheight, width, rheight, width,
rheight - borderRadius)
..lineTo(width, 0)
..lineTo(0, 0);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}
class MessageClipper扩展了CustomClipper{
最终双边界半径=15;
@凌驾
路径getClip(大小){
双倍宽度=大小。宽度;
双倍高度=尺寸。高度;
双rheight=高度-高度/3;
双三分之一=宽度/3;
最终路径=路径()
…lineTo(0,rheight-边界半径)
…立方体(0,rheight-边界半径,0,rheight,边界半径,rheight)
…lineTo(三分之一,rheight)
..lineTo(宽度/2-边界半径、高度边界半径)
…立方(宽度/2-边界半径,高度-边界半径,宽度/2,
高度、宽度/2+边界半径、高度-边界半径)
…线路至(2*1/3,rheight)
..lineTo(宽度边界半径,rheight)
…立方(宽度-边界半径、rheight、宽度、rheight、宽度、,
rheight-边界半径)
…lineTo(宽度,0)
..lineTo(0,0);
返回路径;
}
@凌驾
bool shouldReclip(CustomClipper oldClipper)=>true;
}
我把这个方法叫做这里
Center(
child: ClipPath(
clipper: MessageClipper(),
child: Container(
height: 41.66,
width: 91.63,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
color: Colors.red,
),
child:
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 7,
height: 8,
decoration: BoxDecoration(
color: Color(0xFFCCCCCC),
shape: BoxShape.circle),
),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(
color: Color(0xFFCCCCCC),
shape: BoxShape.circle),
),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(
color: Color(0xFFCCCCCC),
shape: BoxShape.circle),
),
Container(
width: 25,
height: 24,
decoration: BoxDecoration(
color: Color(0xFF1287BA),
shape: BoxShape.circle),
child: Center(
child: Text(
"17",
style: TextStyle(color: Color(0xFFFFFFFF)),
),
),
),
],
),
),)
)
中心(
孩子:克利帕斯(
clipper:MessageClipper(),
子:容器(
身高:41.66,
宽度:91.63,
装饰:盒子装饰(
borderRadius:borderRadius.all(半径.圆形(16.0)),
颜色:颜色,红色,
),
儿童:
划船(
mainAxisAlignment:mainAxisAlignment.space,
儿童:[
容器(
宽度:7,
身高:8,
装饰:盒子装饰(
颜色:颜色(0xFFCCCC),
形状:长方形。圆形),
),
容器(
宽度:7,
身高:8,
装饰:盒子装饰(
颜色:颜色(0xFFCCCC),
形状:长方形。圆形),
),
容器(
宽度:7,
身高:8,
装饰:盒子装饰(
颜色:颜色(0xFFCCCC),
形状:长方形。圆形),
),
容器(
宽度:25,
身高:24,
装饰:盒子装饰(
颜色:颜色(0xFF1287BA),
形状:长方形。圆形),
儿童:中心(
子:文本(
"17",
样式:TextStyle(颜色:颜色(0xFFFFFFFF)),
),
),
),
],
),
),)
)
无法像这样将容器中的项目置于中心
使用此简单的自定义形状订单
:
class MessageBorder extends ShapeBorder {
final bool usePadding;
MessageBorder({this.usePadding = true});
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: usePadding? 20 : 0);
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) {
rect = Rect.fromPoints(rect.topLeft, rect.bottomRight - Offset(0, 20));
return Path()
..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2)))
..moveTo(rect.bottomCenter.dx - 10, rect.bottomCenter.dy)
..relativeLineTo(10, 20)
..relativeLineTo(20, -20)
..close();
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}
@override
ShapeBorder scale(double t) => this;
}
使用代码:
Container(
height: 64,
decoration: ShapeDecoration(
color: Colors.white,
shape: MessageBorder(),
shadows: [
BoxShadow(color: Colors.black, blurRadius: 4.0, offset: Offset(2, 2)),
],
),
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 8),
child: Container(
width: 30,
decoration: BoxDecoration(
color: Colors.blueAccent,
shape: BoxShape.circle,
),
),
),
您可以得到如下结果:
class ButtonMessage extends StatelessWidget {
final String text;
final GestureTapCallback onTap;
const ButtonMessage(this.text, this.onTap);
@override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
elevation: 4,
clipBehavior: Clip.antiAlias,
shape: MessageBorder(),
child: InkWell(
splashColor: Colors.orange,
hoverColor: Colors.blueGrey,
highlightColor: Colors.transparent,
onTap: onTap,
child: Container(
height: 64,
padding: EdgeInsets.only(bottom: 20, right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 6,),
Container(
width: 25,
height: 24,
decoration: BoxDecoration(color: Color(0xFF1287BA), shape: BoxShape.circle),
child: Center(
child: Text(text, style: TextStyle(color: Color(0xFFFFFFFF))),
),
),
],
),
),
),
);
}
}
编辑:如果您希望您的小部件可单击,请使用以下内容:
class ButtonMessage extends StatelessWidget {
final String text;
final GestureTapCallback onTap;
const ButtonMessage(this.text, this.onTap);
@override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
elevation: 4,
clipBehavior: Clip.antiAlias,
shape: MessageBorder(),
child: InkWell(
splashColor: Colors.orange,
hoverColor: Colors.blueGrey,
highlightColor: Colors.transparent,
onTap: onTap,
child: Container(
height: 64,
padding: EdgeInsets.only(bottom: 20, right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 6,),
Container(
width: 25,
height: 24,
decoration: BoxDecoration(color: Color(0xFF1287BA), shape: BoxShape.circle),
child: Center(
child: Text(text, style: TextStyle(color: Color(0xFFFFFFFF))),
),
),
],
),
),
),
);
}
}
class按钮消息扩展了无状态小部件{
最终字符串文本;
最后一个手势点击点击按钮;
const按钮消息(this.text、this.onTap);
@凌驾
小部件构建(构建上下文){
退货(
颜色:颜色,白色,
标高:4,
clipBehavior:Clip.antiAlias,
shape:MessageBorder(),
孩子:InkWell(
颜色:Colors.orange,
hoverColor:Colors.bluegray,
highlightColor:Colors.transparent,
onTap:onTap,
子:容器(
身高:64,
填充:仅限边缘设置(底部:20,右侧:8),
孩子:排(
mainAxisAlignment:mainAxisAlignment.end,
儿童:[
容器(
宽度:7,
身高:8,
装饰:盒子装饰(颜色:颜色(0xFFCCCC),形状:盒子形状。圆圈),
),
容器(宽度:3,),
容器(
宽度:7,
身高:8,
装饰:盒子装饰(颜色:颜色(0xFFCCCC),形状:盒子形状。圆圈),
),
容器(宽度:3,),
容器(
宽度:7,
身高:8,
装饰:盒子装饰(颜色:颜色(0xFFCCCC),形状:盒子形状。圆圈),
),
货柜(宽度:6,),
容器(
宽度:25,
身高:24,
装饰:盒子装饰(颜色:颜色(0xFF1287BA),形状:盒子形状。圆圈),
儿童:中心(
子项:文本(文本,样式:文本样式(颜色:颜色(0xFFFFFF)),
),
),
],
),
),
),
);
}
}
编辑2:带有自定义阴影的可单击阳台:
class ButtonMessage extends StatelessWidget {
final String text;
final GestureTapCallback onTap;
const ButtonMessage(this.text, this.onTap);
@override
Widget build(BuildContext context) {
return Container(
decoration: ShapeDecoration(
shape: MessageBorder(usePadding: false),
shadows: [
BoxShadow(color: Colors.black, blurRadius: 4, offset: Offset(2, 2)),
],
),
child: Material(
color: Colors.white,
clipBehavior: Clip.antiAlias,
shape: MessageBorder(),
child: InkWell(
splashColor: Colors.orange,
hoverColor: Colors.blueGrey,
highlightColor: Colors.transparent,
onTap: onTap,
child: Container(
height: 64,
padding: EdgeInsets.only(bottom: 20, right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 3,),
Container(
width: 7,
height: 8,
decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
),
Container(width: 6,),
Container(
width: 25,
height: 24,
decoration: BoxDecoration(color: Color(0xFF1287BA), shape: BoxShape.circle),
child: Center(
child: Text(text, style: TextStyle(color: Color(0xFFFFFFFF))),
),
),
],
),
),
),
),
);
}
}
class按钮消息扩展了无状态小部件{
最终字符串文本;
最后一个手势点击点击按钮;
const按钮消息(this.text、this.onTap);
@凌驾
小部件构建(构建上下文){
返回容器(
装饰:造型装饰(
形状:MessageBorder(usePadding:false),
阴影:[
BoxShadow(颜色:Colors.black,模糊半径:4,偏移量:偏移量(2,2)),
],
),
儿童:材料(
颜色:颜色,白色,
clipBehavior:Clip.antiAlias,
shape:MessageBorder(),
孩子:InkWell(
颜色:Colors.orange,
hoverColor:Colors.bluegray,
highlightColor:Colors.transparent,
onTap:onTap,
子:容器(
身高:64,
填充:仅限边缘设置(底部:20,右侧:8),
孩子:排(
mainAxisAlignment:mainAxisAlignment.end,
儿童:[
容器(
宽度:7,
身高:8,
装饰:盒子装饰(颜色:颜色(0xFFCCCC),形状:盒子形状。圆圈),
),
容器(宽度:3,),
容器(
宽度:7,
身高:8,
装饰:盒子装饰(颜色:颜色(0xFFCCCC),形状:盒子形状。圆圈),
)