You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter页面添加轮播后GridView懒加载失效的解决办法

解决Flutter嵌套布局中GridView懒加载失效问题

问题原因

  • 你将ScrollController绑定给了嵌套在ListView内的GridView,但GridView设置了NeverScrollableScrollPhysics(),自身不处理滚动,实际滚动由外层ListView负责,导致监听GridView的控制器无法触发滚动到底部的加载逻辑。
  • 原判断条件_scrollController.position.pixels == _scrollController.position.maxScrollExtent容易因精度问题失效,尤其是在嵌套布局中。

修复方案

  1. 将ScrollController绑定到外层的ListView,而非内部的GridView
  2. 替换滚动触发条件为extentAfter < 200(距离底部200px时触发加载),提升稳定性
  3. 给轮播的水平ListView添加滚动物理属性,避免滚动冲突
  4. 新增请求拦截逻辑,防止重复触发加载

修改后的完整代码

class _HomePageState extends State<HomePage> {
  List<String> images = [
    'https://picsum.photos/id/1/200/300',
    'https://picsum.photos/id/2/200/300',
    'https://picsum.photos/id/3/200/300',
  ];

  List<dynamic> data = [];

  bool isLoading = false;

  int page = 1;

  final int perPage = 10;

  ScrollController _scrollController = ScrollController();

  Future<void> fetchData() async {
    if (isLoading) return; // 拦截重复请求
    setState(() {
      isLoading = true;
    });

    final response = await http.get(Uri.parse(
        'https://jsonplaceholder.typicode.com/photos?_page=$page&_limit=$perPage'));

    setState(() {
      isLoading = false;
      page++;
      data.addAll(jsonDecode(response.body));
    });
  }

  @override
  void initState() {
    super.initState();

    fetchData();

    _scrollController.addListener(() {
      // 距离底部200px时触发加载,替代原精确判断
      if (_scrollController.position.extentAfter < 200 && !isLoading) {
        fetchData();
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo'),
      ),
      body: ListView(
        controller: _scrollController, // 绑定到外层ListView
        children: [
          SizedBox(
            height: 200,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              physics: ClampingScrollPhysics(), // 添加滚动物理属性避免冲突
              itemCount: images.length,
              itemBuilder: (BuildContext context, int index) {
                return Image.network(images[index]);
              },
            ),
          ),
          SizedBox(height: 8),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: GridView.builder(
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              itemCount: data.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 8,
                crossAxisSpacing: 8,
                childAspectRatio: 0.75,
              ),
              itemBuilder: (BuildContext context, int index) {
                return Card(
                  child: Column(
                    children: [
                      Expanded(
                        child: Image.network(
                          data[index]['thumbnailUrl'],
                          fit: BoxFit.cover,
                        ),
                      ),
                      SizedBox(height: 8),
                      Text(
                        data[index]['title'],
                        style: TextStyle(fontSize: 16),
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                      ),
                      SizedBox(height: 8),
                      Text(
                        'ID: ${data[index]['id']}',
                        style: TextStyle(fontSize: 12),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
          SizedBox(height: isLoading ? 16 : 0),
          Center(
            child: isLoading
                ? CircularProgressIndicator()
                : SizedBox(),
          ),
        ],
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者M Al

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:25:01