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

Flutter GridView双向滚动问询:固定宽单元格横竖滚动实现需求

实现固定宽度单元格的双向滚动网格

要实现支持水平+垂直滚动、固定宽度单元格的30×30网格,你需要调整原有的CustomScrollView结构,增加水平滚动的外层容器,同时明确控制网格的总宽度来保证单元格尺寸固定。下面是两种可行的方案:

方案1:基于CustomScrollView(保留原Sliver结构)

这种方案延续你原有的SliverGrid实现,通过外层水平滚动容器扩展横向空间,适配你的现有代码习惯:

import 'dart:math';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      home: Scaffold(
        // 外层:水平滚动容器,处理横向滚动需求
        body: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: SizedBox(
            // 固定总宽度:30列 × 单元格宽度(这里设为100,可按需调整)
            width: 30 * 100.0,
            // 内层:保留原有的垂直滚动CustomScrollView
            child: CustomScrollView(
              slivers: <Widget>[
                SliverGrid(
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 30, // 每行固定显示30个单元格
                    childAspectRatio: 0.5, // 宽高比=100/200,确保单元格高度为200
                  ),
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      // 生成30×30=900个单元格,满足最少行列要求
                      if (index >= 900) return null;
                      return Container(
                        width: 100.0, // 明确固定单元格宽度,避免自适应缩放
                        height: 200.0,
                        color: _randomColor(index),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  // 辅助函数:根据index生成固定颜色,避免滚动时颜色闪烁
  Color _randomColor(int index) {
    final random = Random(index);
    return Color.fromRGBO(
      random.nextInt(256),
      random.nextInt(256),
      random.nextInt(256),
      1.0,
    );
  }
}

方案2:基于GridView.builder(性能更优,适合大量数据)

如果单元格数量远超200,推荐使用GridView.builder——它支持懒加载,只会创建可见区域的单元格,能有效降低内存占用:

import 'dart:math';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      home: Scaffold(
        body: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: SizedBox(
            width: 30 * 100.0, // 30列×100宽度,保证单元格尺寸固定
            child: GridView.builder(
              shrinkWrap: true, // 让GridView高度自适应内容,避免多余空白
              physics: const AlwaysScrollableScrollPhysics(), // 保持垂直滚动能力
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 30,
                childAspectRatio: 0.5,
              ),
              itemCount: 900, // 30×30=900个单元格
              itemBuilder: (context, index) {
                return Container(
                  width: 100.0,
                  height: 200.0,
                  color: _randomColor(index),
                );
              },
            ),
          ),
        ),
      ),
    );
  }

  Color _randomColor(int index) {
    final random = Random(index);
    return Color.fromRGBO(
      random.nextInt(256),
      random.nextInt(256),
      random.nextInt(256),
      1.0,
    );
  }
}

关键细节说明:

  1. 水平滚动实现:用SingleChildScrollView设置scrollDirection: Axis.horizontal作为外层容器,让整个网格可以横向滑动。
  2. 固定单元格宽度:通过SizedBox固定网格总宽度为30×单元格宽度,再配合crossAxisCount:30,确保每个单元格的宽度完全符合你设置的固定值,不会自适应缩放。
  3. 垂直滚动保持:内层的CustomScrollView或GridView负责垂直滚动,保留原有的流畅滚动体验。
  4. 性能优化:如果单元格数量极大,优先选择GridView.builder的懒加载模式,避免一次性创建所有单元格导致内存压力过大。

内容的提问来源于stack exchange,提问作者John Mcfetridge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:47:49