需求介绍
某年某月某天,有一个交互,这个交互需要内容区滑动至最右侧继续左滑,跳转至某某页面
调研遍全网没看到(可能是我没找到)实现这个需求的文章,这边自己开发了一个让大家用一用,也记录一下
先来个流程图
1. 监听滚动事件,是否滚动到底部
2. 滚动到底部记录,将isatend标记为true,相反记录为false
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent && _isAtEnd == false) {
setState(() {
_isAtEnd = true;
});
} else if(_scrollController.position.pixels < _scrollController.position.maxScrollExtent && _isAtEnd == true) {
setState(() {
_isAtEnd = false;
});
}
3. 将listview的physics从ClampingScrollPhysics (滚动边缘后会立即停止) 变头BouncingScrollPhysics (允许用户在到达边缘后继续滚动一段距离)模拟继续滚动的拖拽动画
ListView.builder(
physics:_isAtEnd ? BouncingScrollPhysics() : ClampingScrollPhysics(),
controller: _scrollController,
scrollDirection: Axis.horizontal,
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: 100,
color: Colors.orange[(index % 9 + 1) * 100],
child: Center(
child: Text(_isAtEnd? '右滑跳转': '右滑'),
),
);
},
)
4. 判断是否到达底部并继续滚动,将 overflow标记为true
// 检测是否到达底部并且继续滚动
if (offset >= maxScrollExtent) {
double overscroll = offset - maxScrollExtent;
if (overscroll > 0) {
_onReachBottomOverscroll(overscroll);
}
}
void _onReachBottomOverscroll(double overscroll) {
// 自定义事件处理,例如触发某些操作
print('Reached bottom and overscrolled by: $overscroll');
if(_overflow == false){
_overflow = true;
}
5. 在滚动监听事件里判断如果滚动到底部目overflow为true的话执行跳转函数,并将overflow标记为false
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
if (_overflow) {
print('我将跳转');
_overflow = false;
}
}
呈现效果
是个视频 上传不了就截个图吧
代码
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _scrollController = ScrollController();
bool _isAtEnd = false;
bool _overflow = true;
@override
void initState() {
super.initState();
_scrollController.addListener(_scrollListener);
}
void _scrollListener() {
// 获取当前滚动位置
double offset = _scrollController.offset;
double maxScrollExtent = _scrollController.position.maxScrollExtent;
double minScrollExtent = _scrollController.position.minScrollExtent;
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
if (_overflow) {
print('我将跳转');
_overflow = false;
}
}
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent && _isAtEnd == false) {
setState(() {
_isAtEnd = true;
});
} else if(_scrollController.position.pixels < _scrollController.position.maxScrollExtent && _isAtEnd == true) {
setState(() {
_isAtEnd = false;
});
}
// 检测是否到达底部并且继续滚动
if (offset >= maxScrollExtent) {
double overscroll = offset - maxScrollExtent;
if (overscroll > 0) {
_onReachBottomOverscroll(overscroll);
}
}
}
void _onReachBottomOverscroll(double overscroll) {
// 自定义事件处理,例如触发某些操作
print('Reached bottom and overscrolled by: $overscroll');
if(_overflow == false){
_overflow = true;
}
// 可以在这里执行其他操作,比如加载更多数据或展示提示
}
@override
Widget build(BuildContext context) {
return ListView.builder(
physics:_isAtEnd ? BouncingScrollPhysics() : ClampingScrollPhysics(),
controller: _scrollController,
scrollDirection: Axis.horizontal,
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: 100,
color: Colors.orange[(index % 9 + 1) * 100],
child: Center(
child: Text(_isAtEnd? '右滑跳转': '右滑'),
),
);
},
);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}