flutter:無限スクロール用のTabControllerのNotificationListener

Oct 04 2020

4つのタブがあり、遅延読み込みまたは無限スクロールオプションを追加したいと思います。以前、Scroll Controllerを試してみましたが、最後に到達したときです。イベントが複数回発生します。したがって、APIへのFuturehttpリクエストは複数あります。

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;
        },
      );

同じコードをタブ内に配置しようとしましたが、スクロールイベントが検出されません。

回答

Rocx Oct 04 2020 at 12:13

私はそれをうまく動かすことができましたが、これが効率的な方法であるかどうかはわかりません。同様の問題に直面した可能性のある他の人もそうかもしれません。

以下のコードは、アクティブなタブを識別するのに役立ちます。

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) {