如何判断在Flutter中ListView.Builder中的最后一个项目是否已显示在屏幕上

huangapple go评论58阅读模式
英文:

How to tell if the last item in ListView.Builder has been shown to the screen in Flutter

问题

ListView.builder() 中监听滚动并在用户屏幕上显示列表的最后一项时通知的方法是使用 ScrollController。您可以创建一个 ScrollController 并将其分配给 ListView.builder(),然后添加一个监听器以侦听滚动事件。当滚动事件指示列表已滚动到最后一项时,您可以执行所需的操作,例如隐藏 FloatingActionButton。以下是相关代码示例:

import 'package:flutter/material.dart';

class YourWidget extends StatefulWidget {
  @override
  _YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  ScrollController _scrollController = ScrollController();
  bool _showFloatingActionButton = true;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        // Reached the end of the list
        setState(() {
          _showFloatingActionButton = false;
        });
      } else {
        setState(() {
          _showFloatingActionButton = true;
        });
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Your App'),
      ),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: Data.channels.length,
        itemBuilder: (c, index) {
          Channel item = Data.channels[index];
          return Container(
            child: Text(item.name),
          );
        },
      ),
      floatingActionButton: _showFloatingActionButton
          ? FloatingActionButton(
              onPressed: () {
                // Handle FloatingActionButton click
              },
              child: Icon(Icons.add),
            )
          : null,
    );
  }
}

请确保将上述代码嵌入到您的 Flutter 项目中,并根据需要调整按钮的 onPressed 处理程序。这将使 FloatingActionButton 在用户滚动到列表的最后一项时隐藏,以便用户可以看到最后一项而不会被 FloatingActionButton 遮挡。

英文:

all.

I want to listen to the scrolls in the ListView.Builder() in flutter and be notified whenever the last item of the list has been drawn/shown to the screen of the user. I want to hide the FloatingActionButton so the user can see the last item without "view channel" being hidden/blocked by the FloatingActionButton

如何判断在Flutter中ListView.Builder中的最后一个项目是否已显示在屏幕上


ListView.builder(
         itemCount: Data.channels.length,
         itemBuilder: (c, index) {
         Channel item = Data.channels[index];
         return Container(
            child:Text(item.name,
     );
},

答案1

得分: 3

你可以使用ScrollController来跟踪滚动位置。

class DF extends StatefulWidget {
  const DF({super.key});

  @override
  State<DF> createState() => _DFState();
}

class _DFState extends State<DF> {
  final _controller = ScrollController();
  ValueNotifier<bool> isLast = ValueNotifier(false);

  @override
  void initState() {
    super.initState();
    _controller.addListener(() {
      // 你可以尝试使用 _controller.position.atEdge
      if (_controller.position.pixels >= _controller.position.maxScrollExtent - 100) {
        // 100 是项目的高度
        isLast.value = true;
      } else {
        isLast.value = false;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: ValueListenableBuilder(
        valueListenable: isLast,
        builder: (context, value, child) {
          return Visibility(
            visible: value,
            child: FloatingActionButton(
              onPressed: () {},
            ),
          );
        },
      ),
      body: ListView.builder(
        controller: _controller,
        itemCount: 15,
        itemBuilder: (context, index) => Container(
          height: 100,
          color: Colors.red,
          child: Text('$index'),
        ),
      ),
    );
  }
}

另外,你还可以查看 visibility_detector

英文:

You can use ScrollController to track the scroll position.

class DF extends StatefulWidget {
  const DF({super.key});

  @override
  State&lt;DF&gt; createState() =&gt; _DFState();
}

class _DFState extends State&lt;DF&gt; {
  final _controller = ScrollController();
  ValueNotifier&lt;bool&gt; isLast = ValueNotifier(false);

  @override
  void initState() {
    super.initState();
    _controller.addListener(() {
      // you can try _controller.position.atEdge
      if (_controller.position.pixels &gt;= _controller.position.maxScrollExtent - 100) {
        //100 is item height
        isLast.value = true;
      } else {
        isLast.value = false;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: ValueListenableBuilder(
        valueListenable: isLast,
        builder: (context, value, child) {
          return Visibility(
            visible: value,
            child: FloatingActionButton(
              onPressed: () {},
            ),
          );
        },
      ),
      body: ListView.builder(
        controller: _controller,
        itemCount: 15,
        itemBuilder: (context, index) =&gt; Container(
          height: 100,
          color: Colors.red,
          child: Text(&#39;$index&#39;),
        ),
      ),
    );
  }
}

Also you can check visibility_detector.

答案2

得分: 1

你可以通过这段代码来实现

    class _MyHomePageState extends State<MyHomePage> {
      ScrollController scrollController = ScrollController();
      bool _showFloating = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
    
          bottomNavigationBar: Container(height: 100,color: Colors.cyan,width: double.infinity,),
          body: NotificationListener<ScrollNotification>(
              onNotification: (ScrollNotification scrollInfo) {
                if (scrollInfo.metrics.pixels ==
                    scrollInfo.metrics.maxScrollExtent) {
                  setState(() {
                    _showFloating = false;
                  });
                } else {
                  setState(() {
                    _showFloating = true;
                  });
                }
                return false;
              },
              child: ListView.separated(
                  controller: scrollController,
                  itemBuilder: (c, i) {
                    return Container(
                      width: double.infinity,
                      height: 100,
                      color: Colors.red,
                    );
                  },
                  separatorBuilder: (c, i) {
                    return Divider();
                  },
                  itemCount: 10)),
          floatingActionButton:
              _showFloating ? FloatingActionButton(onPressed: () {}) : SizedBox(),
        );
      }
    }
英文:

You can achieve via this code

class _MyHomePageState extends State&lt;MyHomePage&gt; {
  ScrollController scrollController = ScrollController();
  bool _showFloating = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),

      bottomNavigationBar: Container(height: 100,color: Colors.cyan,width: double.infinity,),
      body: NotificationListener&lt;ScrollNotification&gt;(
          onNotification: (ScrollNotification scrollInfo) {
            if (scrollInfo.metrics.pixels ==
                scrollInfo.metrics.maxScrollExtent) {
              setState(() {
                _showFloating = false;
              });
            } else {
              setState(() {
                _showFloating = true;
              });
            }
            return false;
          },
          child: ListView.separated(
              controller: scrollController,
              itemBuilder: (c, i) {
                return Container(
                  width: double.infinity,
                  height: 100,
                  color: Colors.red,
                );
              },
              separatorBuilder: (c, i) {
                return Divider();
              },
              itemCount: 10)),
      floatingActionButton:
          _showFloating ? FloatingActionButton(onPressed: () {}) : SizedBox(),
    );
  }
}

huangapple
  • 本文由 发表于 2023年7月17日 19:01:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76703800.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定