I am using a ListView.builder to render a chat.
The scenario is the following: A user types in a new chat message, when that happens i am storing the new message in state and therefore the itemCount is increased by one.
If i am at the end of the list, I see the new item directly at the top, everything is OK.
However, if I am in the middle of the chat and an item is added, the view scrolls a little bit. How can I disable this behaviour? I guess it kinda makes sense because the scroll offset is still the same double in the ScrollControllers state, but if there is one more item, it looks like it scrolls...
Is there a good way to do this? I guess the manual approach would be to measure the height of the new item and manually set the correct ScrollController offset again.. but meeeh
这是针对在列表顶部添加静态/恒定高度(高度:100)的项目的解决方案。
当我检测到列表长度已更改时,我通过调用 _scrollController.jumpTo(newOffect) 按硬编码项目高度更改偏移位置。
效果很好。当新项目添加到顶部时,列表保持在当前位置,没有可见的跳转。
class FeedWidget extends StatefulWidget {
FeedWidget({
Key key,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _FeedWidgetState();
}
class _FeedWidgetState extends State<FeedWidget> {
var _scrollController = ScrollController();
var _itemsLength = 0;
@override
Widget build(BuildContext context) {
return StreamBuilder<List<FeedItem>>(
stream: Provider.of<FeedRepository>(context).getAll(),
builder: (BuildContext context, AsyncSnapshot<List<FeedItem>> items) {
print('Loaded feed data $items');
switch (items.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
final newItemsLength = items.data.length;
if (_itemsLength != 0 && _itemsLength != newItemsLength) {
final newItemsCount = newItemsLength - _itemsLength;
print('New items detected: $newItemsCount');
final newOffset = _scrollController.offset +
100 * newItemsCount; //item height is 100
print(
'Setting new offest ${_scrollController.offset} -> $newOffset');
_scrollController.jumpTo(newOffset);
}
print('Items length new = $newItemsLength old = $_itemsLength}');
_itemsLength = newItemsLength;
return Flexible(
child: ListView(
key: PageStorageKey('feed'), //keeps scroll position
controller: _scrollController,
padding: EdgeInsets.only(top: 8, bottom: 32),
children: items.data
.map((element) => FeedItemCard(item: element)) //item height is 100
.toList()));
}
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |