Flutter:Flutter:如何制作最好的 Slivers 效果
Flutter: Flutter: How to make finest this Slivers efect
首先抱歉我的英语不好,我会尽力解释自己
我从列表中创建了一个项目,效果如下:
当我滚动填充下方字段时,图像尺寸将减小到最小高度,平面按钮字体大小和平面按钮不透明度也会减小。
问题是:如何使效果更平滑,按钮始终与图像保持相同的距离?
这是代码:
SliverPersistentHeader makeHeader(bool pinned) {
return SliverPersistentHeader(
pinned: pinned,
floating: true,
delegate: _SliverAppBarDelegate(
minHeight: 60.0,
maxHeight: 200.0,
),
);
}
_SliverAppBarDelegate:
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final double minHeight;
final double maxHeight;
final bool hideButtonWhenExpanded;
_SliverAppBarDelegate(
{@required this.minHeight,
@required this.maxHeight,
this.hideButtonWhenExpanded = true});
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final appBarSize = maxHeight - shrinkOffset;
final proportion = 2 - (maxHeight / appBarSize);
final photoToButton = 160 * proportion;
final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion;
return new SizedBox.expand(
child: Container(
color: Colors.white,
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Positioned(
top: 10.0,
child: CircleAvatar(
minRadius: 20.0,
maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0,
backgroundImage: NetworkImage(
'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'),
),
),
Positioned(
left: 0.0,
right: 0.0,
top: photoToButton,
child: Opacity(
opacity: percent,
child: FlatButton(
onPressed: () {},
child: Text(
'Add Photo',
style: TextStyle(
color: Colors.blue, fontSize: 14.0 * proportion),
),
),
),
),
Positioned(
left: 0.0,
right: 0.0,
top: appBarSize - 1.0 > 59.0 ? appBarSize - 1 : 59.0,
child: const Divider(
height: 1,
thickness: 0.5,
),
)
],
),
),
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight !=
oldDelegate
.minHeight
;
}
}
我会感谢所有可能的帮助
您可以在 _SliverAppBarDelegate
:
中使用 Flex
和 Flexible
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final appBarSize = maxHeight - shrinkOffset;
final proportion = 2 - (maxHeight / appBarSize);
final photoToButton = 160 * proportion;
final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion;
return Flex(
direction: Axis.vertical,
children: <Widget>[
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 8,
child: CircleAvatar(
minRadius: 20.0,
maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0,
backgroundImage: NetworkImage(
'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'),
),
),
Flexible(
flex: 2,
child: Opacity(
opacity: percent,
child: FlatButton(
onPressed: () {},
child: Text(
'Add Photo',
style: TextStyle(
color: Colors.blue, fontSize: 14.0 * proportion),
),
),
),
),
const Divider(
height: 1,
thickness: 0.5,
),
],
),
),
],
);
}
结果:
首先抱歉我的英语不好,我会尽力解释自己
我从列表中创建了一个项目,效果如下:
当我滚动填充下方字段时,图像尺寸将减小到最小高度,平面按钮字体大小和平面按钮不透明度也会减小。
问题是:如何使效果更平滑,按钮始终与图像保持相同的距离?
这是代码:
SliverPersistentHeader makeHeader(bool pinned) {
return SliverPersistentHeader(
pinned: pinned,
floating: true,
delegate: _SliverAppBarDelegate(
minHeight: 60.0,
maxHeight: 200.0,
),
);
}
_SliverAppBarDelegate:
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final double minHeight;
final double maxHeight;
final bool hideButtonWhenExpanded;
_SliverAppBarDelegate(
{@required this.minHeight,
@required this.maxHeight,
this.hideButtonWhenExpanded = true});
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final appBarSize = maxHeight - shrinkOffset;
final proportion = 2 - (maxHeight / appBarSize);
final photoToButton = 160 * proportion;
final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion;
return new SizedBox.expand(
child: Container(
color: Colors.white,
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Positioned(
top: 10.0,
child: CircleAvatar(
minRadius: 20.0,
maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0,
backgroundImage: NetworkImage(
'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'),
),
),
Positioned(
left: 0.0,
right: 0.0,
top: photoToButton,
child: Opacity(
opacity: percent,
child: FlatButton(
onPressed: () {},
child: Text(
'Add Photo',
style: TextStyle(
color: Colors.blue, fontSize: 14.0 * proportion),
),
),
),
),
Positioned(
left: 0.0,
right: 0.0,
top: appBarSize - 1.0 > 59.0 ? appBarSize - 1 : 59.0,
child: const Divider(
height: 1,
thickness: 0.5,
),
)
],
),
),
);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight !=
oldDelegate
.minHeight
;
}
}
我会感谢所有可能的帮助
您可以在 _SliverAppBarDelegate
:
Flex
和 Flexible
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final appBarSize = maxHeight - shrinkOffset;
final proportion = 2 - (maxHeight / appBarSize);
final photoToButton = 160 * proportion;
final percent = proportion < 0 || proportion > 1 ? 0.0 : proportion;
return Flex(
direction: Axis.vertical,
children: <Widget>[
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 8,
child: CircleAvatar(
minRadius: 20.0,
maxRadius: 75.0 * proportion > 20 ? 75.0 * proportion : 20.0,
backgroundImage: NetworkImage(
'https://t3.ftcdn.net/jpg/02/33/46/24/240_F_233462402_Fx1yke4ng4GA8TJikJZoiATrkncvW6Ib.jpg'),
),
),
Flexible(
flex: 2,
child: Opacity(
opacity: percent,
child: FlatButton(
onPressed: () {},
child: Text(
'Add Photo',
style: TextStyle(
color: Colors.blue, fontSize: 14.0 * proportion),
),
),
),
),
const Divider(
height: 1,
thickness: 0.5,
),
],
),
),
],
);
}
结果: