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

FittedBox内嵌套的水平ListView无法正常滚动问题咨询

问题原因

  • 横向ListView可滚动的核心前提是:内容总宽度 > ListView自身的视口宽度
  • 你为ListView设置了shrinkWrap: true,该属性会让ListView的视口宽度直接等于所有子项的总宽度,此时内容宽度与视口宽度完全相等,没有可滚动空间,自然无法响应滑动操作。
  • 初始滚动偏移回弹的问题同理:布局完成后ListView计算得到最大可滚动偏移为0,所以会自动回弹到偏移量为0的位置。
  • 移除FittedBox后滚动恢复的原因是:此时ListView的视口宽度等于父容器宽度,远小于20个子项的总宽度,满足滚动条件。

解决方法

核心思路是主动给ListView设置固定视口宽度,保证内容总宽度大于视口宽度,同时适配FittedBox的缩放规则:

  1. 用LayoutBuilder获取FittedBox父容器的实际尺寸
  2. 根据fit: BoxFit.fitHeight规则计算缩放比例:缩放比例 = FittedBox父容器高度 / 子Container固定高度
  3. 计算子Container需要设置的宽度:子Container宽度 = FittedBox父容器宽度 / 缩放比例,该宽度经过FittedBox缩放后会刚好填满父容器的宽度
  4. 移除ListView的shrinkWrap: true属性,因为已经为它的父容器设置了固定宽度,不需要自适应内容宽度

修改后的完整代码

import 'dart:ui';

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scrollBehavior: MyCustomScrollBehavior(),
      home: Scaffold(
          body: Container(
        height: 200,
        child: LayoutBuilder(
          builder: (context, constraints) {
            // 子组件固定高度
            const childFixedHeight = 100.0;
            // 计算FittedBox的缩放比例
            final scale = constraints.maxHeight / childFixedHeight;
            // 计算子组件需要设置的宽度,缩放后刚好适配父容器宽度
            final childWidth = constraints.maxWidth / scale;
            return FittedBox(
              alignment: const Alignment(-1, -1),
              fit: BoxFit.fitHeight,
              child: Container(
                height: childFixedHeight,
                width: childWidth,
                child: ListView.builder(
                    itemCount: 20,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (context, index) => Container(
                        width: 100,
                        height: 100,
                        child: Text(index.toString()),
                        decoration: BoxDecoration(border: Border.all(width: 3, color: Colors.red)))),
              ),
            );
          }
        ),
      )),
    );
  }
}

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:36:02