如何获得 ScrollController 的全尺寸
Posted
技术标签:
【中文标题】如何获得 ScrollController 的全尺寸【英文标题】:How to get full size of a ScrollController 【发布时间】:2017-10-23 18:44:23 【问题描述】:我已将 ScrollController 附加到 [SliverAppBar, SliverList] 的 CustomScrollView
在默认情况下,我会使用 reverse:true 和 animateTo (0.0) 将滚动移动到添加的最后一个元素,但在这种情况下,使用 reverse 也会反转 SliverAppBar/SliverList 的顺序!
所以我想使用 animateTo ( sizeOfScrollableAfterElementAdded ) 但我找不到这个值。
谢谢!
【问题讨论】:
我认为也许将标题更改为 如何以编程方式滚动到 ScrollView 的末尾 会使它更易于访问。 【参考方案1】:您可以使用_scrollController.position.maxScrollExtent
滚动到末尾。确保在帧后回调中执行此操作,以便它包含您刚刚添加的新项目。
这是一个随着更多项目的添加而滚动到末尾的条形列表示例。
import 'package:flutter/scheduler.dart';
import 'package:flutter/material.dart';
void main()
runApp(new MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
class MyHomePage extends StatefulWidget
State createState() => new MyHomePageState();
class MyHomePageState extends State<MyHomePage>
ScrollController _scrollController = new ScrollController();
List<Widget> _items = new List.generate(40, (index)
return new Text("item $index");
);
@override
Widget build(BuildContext context)
return new Scaffold(
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.arrow_downward),
onPressed: ()
setState(()
_items.add(new Text("item $_items.length"));
);
SchedulerBinding.instance.addPostFrameCallback((_)
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
);
,
),
body: new CustomScrollView(
controller: _scrollController,
slivers: [
new SliverAppBar(
title: new Text('Sliver App Bar'),
),
new SliverList(
delegate: new SliverChildBuilderDelegate(
(context, index) => _items[index],
childCount: _items.length,
),
),
],
),
);
【讨论】:
感谢您让我发现这一点:SchedulerBinding.instance.addPostFrameCallback((_)
这个解决方案完美运行,但是在 initState() 中实现这个呢?例如,在聊天应用程序中,您可能希望在开始时滚动到列表底部。怎样才能做到这一点?
@Loolooii 这就是调度程序绑定调用的用途。建立列表并且控制器实际附加到它之后,然后滚动到它的底部。
@ThinkDigital 这个例子中的调度器绑定是onPressed(),对于Loolooii的问题,你如何调度initstate()上的绑定?
对。您只需将其置于 initstate 中即可。并且它安排在当前小部件完成构建时调用它【参考方案2】:
另外,如果您想在开始时立即滚动到列表底部(在 initState() 中),您可以在第一次调用 setState() 之前放置 Collin 解决方案中的以下代码块。
class ExampleState extends State<Example>
void initState()
super.initState();
_scrollController = new ScrollController();
void _getListItems() async
//get list items
SchedulerBinding.instance.addPostFrameCallback((_)
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 100),
curve: Curves.ease,
);
);
setState(()
);
【讨论】:
你能在 initState() 中有异步项吗?我以为那是禁止的?也不应该在 setState 之前检查 if(mounted) 吗?但是这看起来有点奇怪//但可能在正确的轨道上 从外观上看,他只是在那里定义了一个函数,但没有调用它。是的,你可以有异步代码,但你不能使用 await,因为 initState() 不能是异步的。我认为在 initstate 中调用 setstate 没有意义,因为该小部件尚未构建,因此它最初应该使用正确的值构建 根据你的回答我创建了这个类来滚动到列表视图的末尾或顶部***.com/a/68983662/11567596以上是关于如何获得 ScrollController 的全尺寸的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 使用 StreamBuilder 从 firebase 获取数据后,如何使用 ScrollController 跳转到列表视图的底部?
vuetify.js 如何获得 v-container 的全宽
FlutterListView 列表高级功能 ( ScrollController 上拉加载更多 )