gpt4 book ai didi

flutter - 在 flutter 中为 SliverGrid 背景添加边框半径

转载 作者:行者123 更新时间:2023-12-03 03:22:14 29 4
gpt4 key购买 nike

我正在使用 flutter 构建一个应用程序,并在使用 CustomScrollView 内的 SliverGrid 构建项目网格时陷入困境,并且无法添加边框 -到其背景的半径。请注意,我可以为单个网格项添加半径。

这是我尝试过的

Scaffold(
backgroundColor: Colors.orange,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 250.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset(
'assets/images/000.png',
fit: BoxFit.cover,
),
title: Text('Hello there')),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 15,
),
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 30,
),
),
],
),
);

下面这张图是我用上面的代码得到的。我现在需要的是在橙色部分的topLeft和topRight添加圆形边框半径。

enter image description here

最佳答案

您可以向 sliverAppBar 添加形状

return Scaffold(
backgroundColor: Colors.orange,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 250.0,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(bottom: Radius.circular(16))), //like this
flexibleSpace: FlexibleSpaceBar(
background: Container(color: Colors.blueAccent), //changed it because I dont have the image asset
title: Text('Hello there')),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 15,
),
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 100,
),
),
],
),
);
}

enter image description here

如果您想要相反的方式,也许您应该创建一个自定义 ShapeBorder 并覆盖 getOuterPath 以到达形状之外,并使其看起来像橙色一侧是具有形状的一侧。如果您希望以这种方式尝试更新答案,请告诉我

更新

我相信您正在寻找这样的东西 enter image description here

    class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.orange,
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 250.0,
shape: _CustomShape(), //like this
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
fit: BoxFit.cover,
),
title: Text('Hello there'),
),

),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 15,
),
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 100,
),
),
],
),
);
}
}

class _CustomShape extends ShapeBorder {
const _CustomShape({
this.side = BorderSide.none,
this.borderRadius = BorderRadius.zero,
}) : assert(side != null),
assert(borderRadius != null);

final BorderRadiusGeometry borderRadius;

/// The style of this border.
final BorderSide side;

@override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(side.width);

@override
ShapeBorder scale(double t) {
return _CustomShape(
side: side.scale(t),
borderRadius: borderRadius * t,
);
}

@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
assert(t != null);
if (a is ContinuousRectangleBorder) {
return ContinuousRectangleBorder(
side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t),
);
}
return super.lerpFrom(a, t);
}

@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
assert(t != null);
if (b is ContinuousRectangleBorder) {
return ContinuousRectangleBorder(
side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t),
);
}
return super.lerpTo(b, t);
}

@override
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
double length = 16;
return Path()
..lineTo(0, rect.height - length)
..lineTo(rect.width, rect.height - length)
..lineTo(rect.width, 0)
..close();
}

@override
Path getOuterPath(rect, {TextDirection textDirection}) {
double length = 16; //its just a random number I came up with to test the border
return Path()
..lineTo(0, rect.height)
..quadraticBezierTo(length / 4, rect.height - length, length, rect.height - length)
..lineTo(rect.width - length, rect.height - length)
..quadraticBezierTo(rect.width - (length / 4), rect.height - length, rect.width, rect.height)
..lineTo(rect.width, 0)
..close();
}

@override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
if (rect.isEmpty)
return;
switch (side.style) {
case BorderStyle.none:
break;
case BorderStyle.solid:
final Path path = getOuterPath(rect, textDirection: textDirection);
final Paint paint = side.toPaint();
canvas.drawPath(path, paint);
break;
}
}

@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType)
return false;
return other is ContinuousRectangleBorder
&& other.side == side
&& other.borderRadius == borderRadius;
}

@override
int get hashCode => hashValues(side, borderRadius);

}

我所做的是基于 ContinuousRectangleBorder 创建一个自定义 ShapeBorder,但将 getOuterPath 和 getInnerPath 更改为常量值,使其看起来像这样(这是示例,如果您想要一个可以在多个中使用的自定义类)这种情况可能会改变构造函数中的一些其他值)。

我仍然在 SliverAppBar 中使用,因为那是允许我使用 shape 属性更改形状的小部件,但是使用 getOuterPath 我绘制了从小部件的最大高度到 maxHeight - 16 的曲线(只是一个随机数)我想起来了,就像前面的例子,我添加了 BorderRadius.vertical(bottom: Radius.circular(16)))。如果您没有 Sliver AppBar 而是 Scaffold 中的 AppBar,您可以将 CustomScrollView 包装在没有边距且形状为 RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16) 的卡片中) ))) 类似的效果

使用包更新

flutter_group_sliver: ^0.0.2 添加到您的 pubspec.yaml 依赖项

dependencies:
flutter:
sdk: flutter
flutter_group_sliver: ^0.0.2

将其导入到您的项目中并在 CustomScrollView 中使用新类 SliverGroupBuilder(),它基本上是一个制作成 Sliver 的容器,因此您可以在 Sliver 中使用边距、装饰、填充选项

import 'package:flutter_group_sliver/flutter_group_sliver.dart';
Scaffold(
backgroundColor: Colors.pink[100],
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 250.0,
elevation: 0.0,
forceElevated: false,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
"https://happypixelmedia.com/wp-content/uploads/2019/10/Web-design-ideas-to-look-forward-to-in-2020-cover-1.jpg",
fit: BoxFit.cover,
),
title: Text('Hello there'),
),
),
SliverGroupBuilder(
margin: EdgeInsets.zero,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
child: SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 15,
),
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 100,
),
),
)
],
),
)

Scaffold 背景为粉色,SliverGroupBuilder 为橙色,并带有 BorderRadius.vertical(top: Radius.circular(16)),

enter image description here

关闭SliverAppBar

enter image description here

这种方法可以满足您的需求,但是您必须小心脚手架背景的颜色,使其不同,以便您可以看到边框半径

检查https://pub.dev/packages/flutter_group_sliver#-readme-tab-了解更多包装信息

关于flutter - 在 flutter 中为 SliverGrid 背景添加边框半径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61921414/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com