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

Flutter中如何添加包含多个Container的水平ListView

Flutter 实现含多个Container的水平列表视图

Flutter 原生ListView组件即可快速实现水平滚动的Container列表,无需额外引入依赖,可直接将列表嵌入现有Stack布局中,具体实现如下:

核心实现逻辑

  • 水平滚动列表必须设置明确的高度约束,否则会触发横向滚动组件的布局溢出错误,外层用SizedBox或固定高度的Container包裹即可
  • 给ListView设置scrollDirection: Axis.horizontal切换为横向滚动模式
  • 列表项直接返回自定义样式的Container,按需配置圆角、边距、背景、内部子组件即可
  • 若需要实现卡片吸附轮播效果,可直接复用项目已引入的carousel_slider,调整viewportFraction参数控制单屏显示的卡片数量,无需额外依赖

可复用的水平列表代码

Widget horizontalCardList(Size size) {
  // 水平列表必须指定固定高度
  return SizedBox(
    height: 120,
    width: size.width,
    child: ListView.builder(
      scrollDirection: Axis.horizontal,
      // 左右边距和页面现有文本边距对齐
      padding: EdgeInsets.symmetric(horizontal: size.width * 0.08),
      // 替换为你的实际列表数据长度
      itemCount: 6,
      itemBuilder: (context, index) {
        return Container(
          width: 140,
          // 卡片间距
          margin: const EdgeInsets.only(right: 16),
          // 自定义卡片样式
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(12),
            color: Colors.white.withOpacity(0.2),
            // 卡片内需要放背景图时打开下面注释
            // image: DecorationImage(
            //   image: AssetImage('asset/images/canada${index%3+1}.jpg'),
            //   fit: BoxFit.cover
            // )
          ),
          // 卡片内部内容按需替换
          child: Center(
            child: Text(
              '卡片$index',
              style: const TextStyle(color: Colors.white, fontSize: 16),
            ),
          ),
        );
      },
    ),
  );
}

整合到现有项目的完整代码

将列表组件通过Positioned嵌入Stack布局,放在slogan文本下方即可,修改后的完整代码如下:

import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';

class GetStarted extends StatelessWidget {
  final List<String> imagesList = [
    'asset/images/canada3.jpg',
    'asset/images/canada1.jpg',
    'asset/images/canada2.jpg',
  ];

  Widget horizontalCardList(Size size) {
    return SizedBox(
      height: 120,
      width: size.width,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        padding: EdgeInsets.symmetric(horizontal: size.width * 0.08),
        itemCount: 6,
        itemBuilder: (context, index) {
          return Container(
            width: 140,
            margin: const EdgeInsets.only(right: 16),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(12),
              color: Colors.white.withOpacity(0.2),
            ),
            child: Center(
              child: Text(
                '卡片$index',
                style: const TextStyle(color: Colors.white, fontSize: 16),
              ),
            ),
          );
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    return Scaffold(
      body: Stack(
        children: [
          Container(
            height: size.height,
            width: size.width,
            child: CarouselSlider(
              options: CarouselOptions(
                viewportFraction: 1,
                autoPlay: true,
                height: size.height,
                autoPlayInterval: Duration(seconds: 3),
              ),
              items: imagesList
                  .map(
                    (item) => Center(
                      child: Image.asset(
                        item,
                        fit: BoxFit.cover,
                        width: size.width,
                        height: size.height,
                      ),
                    ),
                  )
                  .toList(),
            ),
          ),
          Container(
            width: size.width,
            height: size.height,
            color: Colors.black.withOpacity(0.3),
          ),
          Positioned(
              top: size.height * 0.9,
              left: size.width * 0.08,
              child: const Text(
                'Login',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w800,
                  fontSize: 15,
                ),
              )),
          Positioned(
              top: size.height * 0.9,
              right: size.width * 0.08,
              child: const Text(
                'Skip',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w800,
                  fontSize: 15,
                ),
              )),
          Positioned(
              top: size.height * 0.6,
              left: size.width * 0.08,
              child: const Text(
                'Get matched with local pros for\nyour next home project',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w800,
                  fontSize: 20,
                ),
              )),
          // 新增水平列表,放在slogan下方
          Positioned(
            top: size.height * 0.7,
            left: 0,
            child: horizontalCardList(size),
          )
        ],
      ),
    );
  }
}

注意事项

  • 调整列表高度、卡片宽高、圆角、间距参数时,直接修改对应属性值即可适配设计稿
  • 需要卡片点击交互时,给Container外层包裹GestureDetector或InkWell组件即可绑定点击事件
  • 若需要轮播吸附效果,将ListView替换为已引入的CarouselSlider,设置viewportFraction: 0.7、enableInfiniteScroll: true即可实现一屏多卡的轮播效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:15:38