gpt4 book ai didi

dart - 当项目的下一部分出现时,无限 CustomScrollView 向后滚动

转载 作者:行者123 更新时间:2023-12-04 13:58:50 26 4
gpt4 key购买 nike

在我的应用程序中,我使用 CustomScrollView ,当滚动位置到达 ScrollView 几乎结束时应该加载更多数据(当前是 position.pixels - 100.0 )。该机制工作正常,数据在我滚动时加载,但取决于连接速度(更准确地说,是 api 响应速度)和初始“向下触摸和向上平移”手势速度,此错误出现。不知道如何正确解释它,但是在应用程序启动然后完成加载下一部分数据的那一刻滚动速度很大, ScrollView 有点向相反的方向滚动。它看起来像 ScrollView “射击”或抵抗。这是带有问题表示的 gif:

enter image description here

我创建了对 gif 上发生的事情的模拟:

import 'dart:async';
import 'package:flutter/cupertino.dart';

class ItemService {
final _itemsController = StreamController<List<String>>();
final _loadNextController = StreamController<bool>();

get items => _itemsController.stream;
get isLoadingNext => _loadNextController.stream;

List<String> _current = [];

loadNext() async {
_loadNextController.add(true);
await Future.delayed(Duration(milliseconds: 500));
_current.addAll(List.generate(10, (idx) => 'Item ${_current.length + idx}'));
_itemsController.add(_current);
_loadNextController.add(false);
}

void dispose() {
_itemsController.close();
_loadNextController.close();
}
}

class ItemsScreen extends StatefulWidget {
@override
_ItemsScreenState createState() => _ItemsScreenState();
}

class _ItemsScreenState extends State<ItemsScreen> {
final _scrollController = ScrollController();
double _prevScrollPos = 0.0;

final _service = ItemService();

_onScroll() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScrollPos = _scrollController.position.pixels;
double delta = 100.0;

if (maxScroll - currentScrollPos <= delta && _prevScrollPos - currentScrollPos < 0) {
_service.loadNext();

}

_prevScrollPos = currentScrollPos;
}

@override
void initState() {
_scrollController.addListener(_onScroll);
_service.loadNext();
super.initState();
}

@override
void dispose() {
_scrollController.dispose();
_service.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
/// navbar
CupertinoSliverNavigationBar(
largeTitle: Text('Items'),
automaticallyImplyTitle: false,
previousPageTitle: 'Back',
transitionBetweenRoutes: false,
),

/// items list
StreamBuilder(
stream: _service.items,
builder: (_, snapshot) {
if (snapshot.hasData) {
final items = snapshot.data;

return SliverList(
delegate: SliverChildBuilderDelegate(
(_, int index) {
return Container(
height: 300.0,
margin: const EdgeInsets.only(bottom: 20.0),
color: index % 2 == 0
? CupertinoColors.activeGreen
: CupertinoColors.activeOrange,
child: Text(items[index]),
);
},
childCount: items.length,
),
);
} else {
return SliverFillRemaining(
child: Center(
child: CupertinoActivityIndicator(),
),
);
}
},
),

StreamBuilder(
stream: _service.isLoadingNext,
builder: (_, snapshot) {
if (snapshot.data == true) {
return SliverToBoxAdapter(
child: Container(
// color: Colors.primary,
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Center(
child: CupertinoActivityIndicator(),
),
),
);
} else {
return SliverToBoxAdapter(
child: Container(height: 0),
);
}
},
),

SliverToBoxAdapter(
child: SafeArea(
child: Container(),
bottom: true,
top: false,
),
)
],
),
);
}
}

main() {
runApp(CupertinoApp(
home: ItemsScreen(),
));
}


更新:通过调用 _scrollController.jumpTo(_scrollController.position.pixels); 解决了这个问题之后 _service.loadNext()

最佳答案

只需添加 ClampingScrollPhysics()在 CustomScrollView 上删除反弹物理。

CustomScrollView(
physics: const ClampingScrollPhysics(), // Remove bounce physics
controller: _scrollController,
slivers: <Widget>[
/// navbar
const CupertinoSliverNavigationBar(...)
],
),

关于dart - 当项目的下一部分出现时,无限 CustomScrollView 向后滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55472249/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com