在 Flutter 中,我有一个
TabBarView
,里面有一个 NestedScrollView
,还有两个孩子。这两个子项是可滚动的,并使用 FutureBuilder
构建,当有数据时,它们返回 ListView
。
当没有数据时,它会从服务器获取数据,并返回一个
Text
并提示“尚无数据可显示”。在加载数据之前。然而在这种情况下,您仍然可以仅使用 Text
滚动空白部分,甚至使其消失在屏幕顶部。
如何在不需要时禁用滚动?是否可以使
NestedScrollView
智能地决定天气以启用滚动本身,例如通过比较孩子的高度和屏幕的高度?谢谢!
您可以做一件事,当您的 NestedScrollView
中没有数据时,使用NeverScrollablePhysics 属性
如何?
可以检查是否有数据,如果没有,则创建物理
NeverScrollablePhysics
否则AlwaysScrollableScrollPhysics 属性
代码
// suppose your futurebuilder looks like this
FutureBuilder<String>(
future: your_future,
builder: (BuildContext context, AsyncSnapshot<String> snapshot){
NestedScrollView(
// if the snapshot has some data, then scrollable else not a scrollable widget
physics: snapshot.hasData ? AlwaysScrollableScrollPhysics() : NeverScrollableScrollPhysics()
)
}
)
或
您可以做一件事,在您的 ListView
或您正在使用的任何视图中使用
primary property。 执行此主要操作:false。它将做的是告诉小部件它不是主要的,因此只能在它们到达底部并且更多数据等待显示时才被考虑。
我发现关键不是滚动,而是
SliverAppBar
覆盖了TabBarView
的顶部。解决方案是将 SliverOverlapAbsorber
与 SliverSafeArea
一起使用,并在 https://github.com/flutter/flutter/issues/27906#issuecomment-499043685 的帮助下
示例代码:
SliverOverlapAbsorber(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
sliver: SliverSafeArea(
sliver: SliverAppBar(
floating: true,
pinned: true,
bottom: TabBar(
tabs: [
Tab(text: "Posts"),
Tab(text: "Likes"),
],
),
expandedHeight: 450,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: Scaffold(
body: Container(),
),
),
),
),
),
使用可以这样做 你必须使用 标题中的
SliverOverlapAbsorber
和
在嵌套滚动视图的主体中,您必须使用
SliverOverlapInjector
作为自定义滚动视图的第一个子元素来吸收滚动
这是示例代码,这样可以实现所需的行为
NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverSafeArea(
sliver: SliverAppBar(
floating: true,
pinned: true,
expandedHeight: 450,
),
),
),
];
},
body: Builder(
builder:(context){
return
CustomScrollView(slivers: [
SliverOverlapInjector(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
), // this to absorb the scroll
// rest of the ui
SliverToBoxAdapter(child: Container(
height: 40,
color: Colors.red
)),
]);}
)),