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

如何在Flutter健康应用中实现BoxDecoration下方的水平ListView

Flutter健康应用首页:添加水平ListView实现方案

我是Flutter新手,正在做一款健康应用的首页,想在现有带BoxDecoration的功能按钮容器下方添加一个水平ListView。

设计图与当前效果

  • Figma设计图:
    Figma设计图
  • 当前实现效果:
    当前实现效果

现有代码

//import 'dart:js';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/get_navigation.dart';
import 'package:medreminder/NewsArticle/news_home.dart';
import 'package:medreminder/Recipe/recipe_home.dart';
import 'package:medreminder/Reminder/ui/theme.dart';
import 'package:medreminder/TipsAndTricks/screens/tips_screen.dart';
import 'Reminder/home_reminder.dart';
import 'Reminder/ui/widgets/button.dart';
import 'package:medreminder/main.dart';
import 'package:medreminder/home_page.dart';

void main() {
  // debugPaintSizeEnabled = true;
  runApp(const HomePage());
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Mr. Health App"),
          backgroundColor: Color(0XFF0080FE),
        ),
        body: Stack(
          alignment: Alignment.topCenter,
          children: [
            Image.asset('images/MenuImg.jpg'),
            Container(
              height: 250,
              width: 310,
              margin: const EdgeInsets.only(top: 150),
              padding: const EdgeInsets.only(
                left: 20,
                right: 20,
                top: 15,
                bottom: 15,
              ),
              decoration: BoxDecoration(
                borderRadius: const BorderRadius.all(Radius.circular(25.0)),
                color: context.theme.backgroundColor,           
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withOpacity(0.1),
                    spreadRadius: 2,
                    blurRadius: 5,
                    offset: const Offset(0, 6),
                  ),
                ],
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                       Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/reminder.png'),
                      iconSize: 45,
                      onPressed: () {
                        Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => const ReminderHomePage()),
                        );
                      },
                    ),
                    Text("Medicine\nReminder", style: normalStyle,)
                  ],
                ),
                Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/news.png'),
                      iconSize: 45,
                      onPressed: () {
                         Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => NewsHomePage()),
                        );
                      },
                    ),
                    Text("  News \n& Article", style: normalStyle)
                  ],
                ),
                Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/recipe.png'),
                      iconSize: 45,
                      onPressed: () {
                        Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => RecipeHomePage()),
                        );
                      },
                    ),
                    Text("Healty Food \n     Recipe", style: normalStyle)
                  ],
                ),
              ],
            ),
            SizedBox(height: 10,),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/tips.png'),
                      iconSize: 45,
                      onPressed: () {
                        Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => const TipsList()),
                        );
                      },
                    ),
                    Text("Tips &\n Tricks", style: normalStyle,)
                  ],
                ),
                Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/about.png'),
                      iconSize: 45,
                      onPressed: () {
                      },
                    ),
                    Text("About Us\n", style: normalStyle)
                  ],
                ),
                Column(
                  children: [
                    IconButton(
                      icon: Image.asset('images/recipe.png'),
                      iconSize: 45,
                      onPressed: () {},
                    ),
                    Text("Healty Food \n     Recipe", style: normalStyle)
                  ],
                ),
                    ],
                  )
                ],
              ),
            ),
          ],
        ));
  }
}

修改方案与完整代码

原来的Stack布局适合层叠元素,要实现上下排列的容器和ListView,换成Column更方便。同时添加水平ListView,具体修改如下:

  1. 将body里的Stack替换为Column,背景图作为第一个子项,然后是功能容器,最后是水平ListView。
  2. 给功能容器添加margin让它和背景图、ListView保持合适间距。
  3. 实现水平ListView,设置scrollDirection: Axis.horizontal,并自定义item样式。

修改后的完整代码:

//import 'dart:js';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/get_navigation.dart';
import 'package:medreminder/NewsArticle/news_home.dart';
import 'package:medreminder/Recipe/recipe_home.dart';
import 'package:medreminder/Reminder/ui/theme.dart';
import 'package:medreminder/TipsAndTricks/screens/tips_screen.dart';
import 'Reminder/home_reminder.dart';
import 'Reminder/ui/widgets/button.dart';
import 'package:medreminder/main.dart';
import 'package:medreminder/home_page.dart';

void main() {
  // debugPaintSizeEnabled = true;
  runApp(const HomePage());
}

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

  // 模拟水平ListView的数据
  final List<Map<String, String>> listItems = [
    {"title": "健康贴士1", "image": "images/tip1.png"},
    {"title": "饮食指南", "image": "images/diet.png"},
    {"title": "运动计划", "image": "images/exercise.png"},
    {"title": "睡眠建议", "image": "images/sleep.png"},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Mr. Health App"),
        backgroundColor: const Color(0XFF0080FE),
      ),
      body: SingleChildScrollView( // 允许页面整体滚动
        child: Column(
          children: [
            // 顶部背景图
            Image.asset('images/MenuImg.jpg'),
            // 功能按钮容器
            Container(
              height: 250,
              width: 310,
              margin: const EdgeInsets.symmetric(vertical: 20),
              padding: const EdgeInsets.only(
                left: 20,
                right: 20,
                top: 15,
                bottom: 15,
              ),
              decoration: BoxDecoration(
                borderRadius: const BorderRadius.all(Radius.circular(25.0)),
                color: context.theme.backgroundColor,           
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withOpacity(0.1),
                    spreadRadius: 2,
                    blurRadius: 5,
                    offset: const Offset(0, 6),
                  ),
                ],
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/reminder.png'),
                            iconSize: 45,
                            onPressed: () {
                              Navigator.of(context, rootNavigator: true).push(
                                MaterialPageRoute(builder: (context) => const ReminderHomePage()),
                              );
                            },
                          ),
                          Text("Medicine\nReminder", style: normalStyle,)
                        ],
                      ),
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/news.png'),
                            iconSize: 45,
                            onPressed: () {
                               Navigator.of(context, rootNavigator: true).push(
                                MaterialPageRoute(builder: (context) => NewsHomePage()),
                              );
                            },
                          ),
                          Text("  News \n& Article", style: normalStyle)
                        ],
                      ),
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/recipe.png'),
                            iconSize: 45,
                            onPressed: () {
                              Navigator.of(context, rootNavigator: true).push(
                                MaterialPageRoute(builder: (context) => RecipeHomePage()),
                              );
                            },
                          ),
                          Text("Healty Food \n     Recipe", style: normalStyle)
                        ],
                      ),
                    ],
                  ),
                  const SizedBox(height: 10,),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/tips.png'),
                            iconSize: 45,
                            onPressed: () {
                              Navigator.of(context, rootNavigator: true).push(
                                MaterialPageRoute(builder: (context) => const TipsList()),
                              );
                            },
                          ),
                          Text("Tips &\n Tricks", style: normalStyle,)
                        ],
                      ),
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/about.png'),
                            iconSize: 45,
                            onPressed: () {},
                          ),
                          Text("About Us\n", style: normalStyle)
                        ],
                      ),
                      Column(
                        children: [
                          IconButton(
                            icon: Image.asset('images/recipe.png'),
                            iconSize: 45,
                            onPressed: () {},
                          ),
                          Text("Healty Food \n     Recipe", style: normalStyle)
                        ],
                      ),
                    ],
                  )
                ],
              ),
            ),
            // 水平ListView
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    "健康资讯",
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 10),
                  SizedBox(
                    height: 180, // 设置ListView高度
                    child: ListView.builder(
                      scrollDirection: Axis.horizontal,
                      itemCount: listItems.length,
                      itemBuilder: (context, index) {
                        final item = listItems[index];
                        return Container(
                          width: 150,
                          margin: const EdgeInsets.only(right: 12),
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(16),
                            color: Colors.white,
                            boxShadow: [
                              BoxShadow(
                                color: Colors.black.withOpacity(0.1),
                                blurRadius: 4,
                                offset: const Offset(0, 2),
                              )
                            ]
                          ),
                          child: Column(
                            children: [
                              ClipRRect(
                                borderRadius: const BorderRadius.only(
                                  topLeft: Radius.circular(16),
                                  topRight: Radius.circular(16),
                                ),
                                child: Image.asset(
                                  item["image"]!,
                                  height: 120,
                                  width: double.infinity,
                                  fit: BoxFit.cover,
                                ),
                              ),
                              Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Text(
                                  item["title"]!,
                                  textAlign: TextAlign.center,
                                  style: const TextStyle(fontSize: 14),
                                ),
                              )
                            ],
                          ),
                        );
                      },
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 20),
          ],
        ),
      ),
    );
  }
}

关键说明

  • 用SingleChildScrollView包裹Column,避免页面内容超出屏幕时出现溢出问题。
  • 水平ListView通过scrollDirection: Axis.horizontal实现,设置固定高度确保布局稳定。
  • 可以根据设计图调整ListView的item样式、数据和间距,匹配UI需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:15:20