Flutter:如何使用 SliverList 将 CupertinoActivityIndicator 放入 customScrollView
Flutter: How to put a CupertinoActivityIndicator into a customScrollView with SliverList
这是我想要实现的模型 - 它是 CupertinoSliverNavigationBar 下的 CupertinoActivityIndicator,用于通知用户正在下载数据。
下载后,它应该如下所示:
现在,我一直在尝试使用以下代码来获得这种效果:
List<Trade> trades = [];
showLoadingDialog() {
return trades.length == 0;
}
getBody() {
if (showLoadingDialog()) {
return getProgressDialog();
} else {
return getTradeItemList();
}
}
getTradeItemList() {
return new CupertinoPageScaffold(
child: new CustomScrollView(slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: const Text('Coffee Shop'),
),
getBody(),
]));
}
getProgressDialog() {
return new Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
),
child: new Center(child: const CupertinoActivityIndicator()));
}
但是,我收到此错误是因为我正在尝试将非 RenderSliver 类型放入 Sliver。换句话说,我将 CupertinoActivityIndicator 放入 Sliver 中,但代码拒绝了它。
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ The
following assertion was thrown building Container(bg:
BoxDecoration(color: Color(0xffffffff))): A RenderViewport expected a
child of type RenderSliver but received a child of type
RenderDecoratedBox. RenderObjects expect specific types of children
because they coordinate with their children during layout and paint.
For example, a RenderSliver cannot be the child of a RenderBox because
a RenderSliver does not understand the RenderBox layout protocol.
最接近我想要的效果显示在下面的 gif 中。但是,您可以清楚地看到,当 CupertinoActivityIndicator 可见时,CupertinoSliverNavigationBar 未显示。只有在数据下载后,显示 "Coffee Shop" 的 CupertinoSliverNavigationBar 才可见。
我使用以下代码实现了上述目标:
List<Trade> trades = [];
showLoadingDialog() {
return trades.length == 0;
}
getBody() {
if (showLoadingDialog()) {
return getProgressDialog();
} else {
return getTradeItemList();
}
}
getProgressDialog() {
return new Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
),
child: new Center(child: const CupertinoActivityIndicator()));
}
getTradeItemList() {
return new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: const Text('Coffee Shop'),
),
new SliverPadding(
// Top media padding consumed by CupertinoSliverNavigationBar.
// Left/Right media padding consumed by Tab1RowItem.
padding: MediaQuery
.of(context)
.removePadding(
removeTop: true,
removeLeft: true,
removeRight: true,
)
.padding,
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Tab1RowItem(
index: index,
lastItem: index == trades.length - 1,
color: "Coffee Beans",
colorName: "Buy coffee now",
);
},
childCount: trades.length,
),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return getBody();
}
@override
void initState() {
super.initState();
loadDataTrades();
}
谁能告诉我怎样才能达到我想要的效果?
Widget _mainFrame;
@override
Widget build(BuildContext context) {
return new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: const Text("Coffe Shop"),
),
_mainFrame,
],
);
}
Widget _beforeDataLoaded() {
return new SliverFillRemaining(
child: new Container(
child: new Center(
child: new CupertinoActivityIndicator(),
),
),
);
}
Widget _dataLoadComplete() {
return new SliverList(
// Your list items
);
}
如果加载完成,您将 _mainFrame 小部件从 CupertionActivityIndicator 更改为您的列表视图。
这是我想要实现的模型 - 它是 CupertinoSliverNavigationBar 下的 CupertinoActivityIndicator,用于通知用户正在下载数据。
下载后,它应该如下所示:
现在,我一直在尝试使用以下代码来获得这种效果:
List<Trade> trades = [];
showLoadingDialog() {
return trades.length == 0;
}
getBody() {
if (showLoadingDialog()) {
return getProgressDialog();
} else {
return getTradeItemList();
}
}
getTradeItemList() {
return new CupertinoPageScaffold(
child: new CustomScrollView(slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: const Text('Coffee Shop'),
),
getBody(),
]));
}
getProgressDialog() {
return new Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
),
child: new Center(child: const CupertinoActivityIndicator()));
}
但是,我收到此错误是因为我正在尝试将非 RenderSliver 类型放入 Sliver。换句话说,我将 CupertinoActivityIndicator 放入 Sliver 中,但代码拒绝了它。
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ The following assertion was thrown building Container(bg: BoxDecoration(color: Color(0xffffffff))): A RenderViewport expected a child of type RenderSliver but received a child of type RenderDecoratedBox. RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.
最接近我想要的效果显示在下面的 gif 中。但是,您可以清楚地看到,当 CupertinoActivityIndicator 可见时,CupertinoSliverNavigationBar 未显示。只有在数据下载后,显示 "Coffee Shop" 的 CupertinoSliverNavigationBar 才可见。
我使用以下代码实现了上述目标:
List<Trade> trades = [];
showLoadingDialog() {
return trades.length == 0;
}
getBody() {
if (showLoadingDialog()) {
return getProgressDialog();
} else {
return getTradeItemList();
}
}
getProgressDialog() {
return new Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
),
child: new Center(child: const CupertinoActivityIndicator()));
}
getTradeItemList() {
return new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
const CupertinoSliverNavigationBar(
largeTitle: const Text('Coffee Shop'),
),
new SliverPadding(
// Top media padding consumed by CupertinoSliverNavigationBar.
// Left/Right media padding consumed by Tab1RowItem.
padding: MediaQuery
.of(context)
.removePadding(
removeTop: true,
removeLeft: true,
removeRight: true,
)
.padding,
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Tab1RowItem(
index: index,
lastItem: index == trades.length - 1,
color: "Coffee Beans",
colorName: "Buy coffee now",
);
},
childCount: trades.length,
),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return getBody();
}
@override
void initState() {
super.initState();
loadDataTrades();
}
谁能告诉我怎样才能达到我想要的效果?
Widget _mainFrame;
@override
Widget build(BuildContext context) {
return new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: const Text("Coffe Shop"),
),
_mainFrame,
],
);
}
Widget _beforeDataLoaded() {
return new SliverFillRemaining(
child: new Container(
child: new Center(
child: new CupertinoActivityIndicator(),
),
),
);
}
Widget _dataLoadComplete() {
return new SliverList(
// Your list items
);
}
如果加载完成,您将 _mainFrame 小部件从 CupertionActivityIndicator 更改为您的列表视图。