flutter - TabController 中的 NotificationListener 用于无限滚动
问题描述
我有 4 个选项卡,我想在其中添加延迟加载或无限滚动选项。早些时候我尝试过使用 Scroll Controller,但是当它到达末尾时。事件触发不止一次。因此对 API 有多个 Future http 请求。
我阅读了一些关于 SO 的问题,发现我可能需要使用 NotificationListener。我不确定我是否需要为所有选项卡定义一次或所有选项卡。我不知道如何使用 NotificationListener。
class _Searchstate extends State<Search> with SingleTickerProviderStateMixin{
ScrollController _scrollController = new ScrollController();
final _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _controller;
TabBarView(
controller: _controller,
children: [
// Text("TAB ONE CONTENT"),
RefreshIndicator(
onRefresh: refreshData,
child:Container(
decoration: BoxDecoration(
color: Colors.black87,
),
padding: EdgeInsets.only(top: 10, bottom: 5),
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ListView.builder(
controller: _scrollcontroller,
itemCount: (recommended) ? lists.length : searchlists.length,
itemBuilder: (BuildContext context, int index) {
return buildList1(context, index);
}),
),
),
//Text("TAB TWO CONTENT"),
RefreshIndicator(
onRefresh: refreshData1,
child:Container(
decoration: BoxDecoration(
color: Colors.black54,
),
padding: EdgeInsets.only(top: 10, bottom: 5),
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ListView.builder(
controller: _scrollcontroller,
itemCount: (nearme) ? lists1.length : searchlists1.length,
itemBuilder: (BuildContext context, int index) {
return buildList2(context, index);
}),
),
),
下面是我使用 Listview.Builder 显示来自数据库的数据的 buildList。我也尝试在下面使用 ScrollController。
Widget buildList1(BuildContext context, int index) {
_scrollController.addListener((){
print(_scrollController.position.pixels);
print(_scrollController.position.maxScrollExtent);
if(_scrollController.position.pixels == _scrollController.position.maxScrollExtent){
print(recommended);
if(recommended){
//getData();
print('getData()1;');
}
// getData();
}
});
我只在这个问题中添加了一些相关代码,因为完整代码很长。
编辑
我尝试使用通知侦听器,如果我在 Scaffold 周围定义它一次,那么它至少可以工作,我可以看到滚动事件,但我有 4 个选项卡,我不确定如何为所有人实现它。因为很难为所有这 4 个选项卡设置条件。
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
child:Scaffold(
---- -- - - - - - More Codes -----
onNotification: (notificationInfo) {
if (notificationInfo is ScrollEndNotification) {
print("scroll");
print("detail:"+notificationInfo.dragDetails.toString());
/// your code
}
return true;
},
);
我试图将相同的代码放在选项卡中,但它没有检测到滚动事件。
解决方案
我设法让它工作,但不确定这是否有效。可能是其他可能面临类似问题的人。
下面的代码将有助于识别活动选项卡。
void initState(){
_controller = TabController(vsync: this, length: 4);
currentTab = (_controller.index);
_controller.addListener(() {
if(_controller.indexIsChanging) {
print("tab is animating. from active (getting the index) to inactive(getting the index) ");
}else {
//tab is finished animating you get the current index
print(_controller.index);
currentTab = (_controller.index);
_handleTabSelection();
}
});
下面的代码是我在 NotificationListner 中添加的。
onNotification: (notificationInfo) {
if (notificationInfo is ScrollEndNotification && notificationInfo.metrics.pixels == notificationInfo.metrics.maxScrollExtent) {
print("scroll");
if(currentTab == 0){
if(recommended == true && tab0 == 'Suggested' ){
// getData();
print('fire the 1 event');
}else{
print('Name()1;');
}
}
if(currentTab == 1){
if(nearme == true && tab1 == 'Near Me'){
//getData();
print('fire the 2nd event ');
}else{
}
}
if(currentTab == 2){
if(byRating == true && tab2 == 'By Rating'){
//getData();
print('fire the 3rd event');
}else{
}
}
if(currentTab == 3){
if(byprice == true && tab3 == 'Active'){
//getData();
print('fire the 4 event');
}else{
}
}
/// your code
}
return true;
},
);
编辑:因为我有多次点击,所以上面的代码也在左右滚动上触发。为防止这种情况发生,我已将代码更改为如下。
if (notificationInfo is ScrollEndNotification && notificationInfo.metrics.axisDirection == AxisDirection.down && notificationInfo.metrics.pixels == notificationInfo.metrics.maxScrollExtent) {