This is a mockup of what I want to achieve - it is a CupertinoActivityIndicator underneath a CupertinoSliverNavigationBar for notifying the user that the data is being downloaded.
Once it is downloaded, it should look like so:
Now, I have been trying to get this effect using the following code:
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()));
}
However, I'm receiving this error because I'm trying to put a non-RenderSliver type into a Sliver. In other words, I'm putting in an CupertinoActivityIndicator into a Sliver and the code is rejecting it.
══╡ 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.
The closest I could get to achieving the effect I want is displayed in the gif below. However, as you can clearly see, the CupertinoSliverNavigationBar is not being displayed when the CupertinoActivityIndicator is visible. It is only after the data has been downloaded that the CupertinoSliverNavigationBar that says "Coffee Shop" is visible.
I achieved the above using the following code:
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();
}
Can anyone tell me how I can achieve the effect I want?
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
);
}
You change the _mainFrame Widget from the CupertionActivityIndicator to your listview if the load finished.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With