如何在Flutter中构建水平滚动UI:底部等级区域滚动、上方图片固定
Flutter 实现固定顶部图片+底部水平滚动等级栏的UI
核心实现思路
通过Stack组件实现分层布局:
- 上层放置固定不动的图片容器,设置合适的宽高和对齐方式
- 下层使用
SingleChildScrollView包裹Row(或直接用ListView.builder)实现水平滚动的等级元素区域,同时添加底部的直线装饰
完整代码示例
import 'package:flutter/material.dart'; class JourneyProgressUI extends StatefulWidget { const JourneyProgressUI({super.key}); @override State<JourneyProgressUI> createState() => _JourneyProgressUIState(); } class _JourneyProgressUIState extends State<JourneyProgressUI> { // 模拟等级数据:头像标识、是否点亮星星 final List<Map<String, dynamic>> levelData = List.generate( 8, (index) => { 'avatarTag': 'level_$index', 'isStarActive': index <= 3, // 前4个星星默认点亮 }, ); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), child: Column( children: [ // 固定顶部的图片区域 Container( width: double.infinity, height: 200, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), image: const DecorationImage( image: NetworkImage('https://picsum.photos/800/200'), // 替换为你的顶部图片资源 fit: BoxFit.cover, ), ), ), const SizedBox(height: 32), // 底部水平滚动的等级区域 Stack( alignment: Alignment.bottomCenter, children: [ // 底部贯穿的直线 Container( height: 2, color: Colors.grey.shade300, ), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: levelData.map((item) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( children: [ // 星星图标 Icon( Icons.star, color: item['isStarActive'] ? Colors.amber : Colors.grey.shade300, size: 32, ), const SizedBox(height: 12), // 头像容器 Container( width: 56, height: 56, decoration: BoxDecoration( borderRadius: BorderRadius.circular(28), border: Border.all(color: Colors.grey.shade300, width: 2), image: DecorationImage( image: NetworkImage('https://picsum.photos/100/100?random=${item['avatarTag']}'), fit: BoxFit.cover, ), ), ), ], ), ); }).toList(), ), ), ], ), ], ), ), ), ); } }
关键细节说明
- 固定图片:直接用
Container包裹图片放在Column上部,完全独立于滚动区域,不会随底部滚动 - 水平滚动区域:
SingleChildScrollView设置scrollDirection: Axis.horizontal实现横向滚动,内部Row承载所有等级元素 - 底部直线:通过
Stack将直线置于滚动区域下方,保证直线始终贯穿滚动区域的底部 - 等级元素样式:星星通过
isStarActive字段控制点亮状态,头像使用圆形容器实现圆角效果
扩展优化建议
- 若等级元素数量较多,建议替换
Row为ListView.builder,减少不必要的Widget渲染,提升性能 - 可添加滚动监听,实现滚动时的等级高亮交互
- 根据平台自定义滚动物理效果:iOS用
BouncingScrollPhysics(),Android用ClampingScrollPhysics()
内容的提问来源于stack exchange,提问作者Adarsh Yashvanth
相关产品推荐
相关产品推荐

