【发布时间】:2019-10-18 18:55:31
【问题描述】:
我想将列表标题作为粘性标题。给定标题的背景应该是透明的,并且在滚动标题“下方”的列表元素时应该消失并且用户应该看到列表视图后面的背景图像。
我正在使用sticky_headers 包来获得粘性标题效果。但我只是从 Flutter 开始我的冒险,对小部件渲染了解不多。
【问题讨论】:
标签: list flutter header widget rendering
我想将列表标题作为粘性标题。给定标题的背景应该是透明的,并且在滚动标题“下方”的列表元素时应该消失并且用户应该看到列表视图后面的背景图像。
我正在使用sticky_headers 包来获得粘性标题效果。但我只是从 Flutter 开始我的冒险,对小部件渲染了解不多。
【问题讨论】:
标签: list flutter header widget rendering
我设法使用 ShaderMask 完成了这项工作。这个想法是我计算我的列表项中的标题在哪里并将这部分屏蔽掉。
列表小部件的关键部分是:
@override
Widget build(BuildContext context) => ListView.builder(
padding: _padding, itemCount: _sectionCount, itemBuilder: _sectionHeader);
StickyHeader _sectionHeader(BuildContext context, int sectionIndex) {
final GlobalKey eventListHeaderKey = GlobalKey();
final GlobalKey shaderMaskKey = GlobalKey();
final AppStyle appStyle = AppStyle.of(context);
return StickyHeader(
header: Container(
key: eventListHeaderKey,
child: _sectionHeaderBuilder(context, sectionIndex)),
content: ShaderMask(
key: shaderMaskKey,
shaderCallback: (Rect rect) =>
_listShader(appStyle, eventListHeaderKey, shaderMaskKey, rect),
blendMode: BlendMode.dstIn,
child: Container(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _sectionElementsCountHandler(sectionIndex),
itemBuilder: (BuildContext context, int index) =>
_elementBuilder(context, sectionIndex, index)))));
}
Shader _listShader(AppStyle appStyle, GlobalKey listHeaderKey,
GlobalKey shaderMaskKey, Rect rect) {
final RenderBox listHeaderRenderBox =
listHeaderKey.currentContext.findRenderObject();
final Offset offset = listHeaderRenderBox.localToGlobal(Offset.zero);
final RenderBox shaderMaskRenderBox =
shaderMaskKey.currentContext.findRenderObject();
final Offset offset2 = shaderMaskRenderBox.globalToLocal(offset);
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: <double>[
0,
(rect.top + offset2.dy) / rect.height,
(rect.top + offset2.dy) / rect.height,
1
],
colors: <Color>[
appStyle.colors.transparent,
appStyle.colors.transparent,
appStyle.colors.white,
appStyle.colors.white
]).createShader(Rect.fromLTWH(0, 0, rect.width, rect.height));
}
【讨论】: