Flutter实现横向滚动多容器网格:解决单元素显示问题
实现Flutter横向滚动的天气预报网格
要实现横向滚动的5天天气预报网格,你需要将单条天气卡片封装为可复用组件,并通过GridView配置横向滚动属性。以下是具体解决方案:
步骤1:封装单条天气卡片组件
将你现有的天气卡片逻辑抽离为独立Widget,方便批量生成:
class DailyWeatherCard extends StatelessWidget { final String weatherDesc; final Widget weatherIconInside; final String minTemp; final String maxTemp; const DailyWeatherCard({ super.key, required this.weatherDesc, required this.weatherIconInside, required this.minTemp, required this.maxTemp, }); @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.symmetric(horizontal: 5.w), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), color: Colors.white, elevation: 10, child: SizedBox( width: 180.w, // 固定卡片宽度,确保多卡片并排显示 child: Row( children: [ Padding( padding: EdgeInsets.only(top: 5.h, left: 10.w), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 70.w, height: 70.h, child: weatherIconInside, ), Text( weatherDesc, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 14.sp, letterSpacing: 0.2, color: AppTheme.grey, ), ), ], ), ), Padding( padding: EdgeInsets.only(top: 5.h, left: 10.w), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Min', style: TextStyle( fontWeight: FontWeight.w400, fontSize: 16.sp, letterSpacing: 0.2, color: AppTheme.grey, ), ), Text( '$minTemp \u2103', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 24.sp, letterSpacing: 0.2, color: AppTheme.grey, ), ), SizedBox( width: 60.w, child: Divider(color: Colors.black, thickness: 1.0), // 替换原粗边框为分割线 ), Text( 'Max', style: TextStyle( fontWeight: FontWeight.w400, fontSize: 16.sp, letterSpacing: 0.2, color: AppTheme.grey, ), ), Text( '$maxTemp \u2103', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 24.sp, letterSpacing: 0.2, color: AppTheme.grey, ), ), SizedBox(height: 10.h) ], ), ), ], ), ), ), ); } }
步骤2:配置横向滚动GridView
在页面中使用GridView.builder绑定API数据,实现横向滚动效果:
// 模拟API返回的5天天气数据,实际开发替换为真实接口数据 final List<Map<String, dynamic>> dailyWeatherList = [ { 'weatherDesc': 'Sunny', 'minTemp': '18', 'maxTemp': '28', 'icon': Icon(Icons.sunny, color: Colors.amber), }, { 'weatherDesc': 'Cloudy', 'minTemp': '17', 'maxTemp': '26', 'icon': Icon(Icons.cloud, color: Colors.grey), }, { 'weatherDesc': 'Rainy', 'minTemp': '15', 'maxTemp': '22', 'icon': Icon(Icons.rainy, color: Colors.blue), }, { 'weatherDesc': 'Windy', 'minTemp': '16', 'maxTemp': '25', 'icon': Icon(Icons.wind_power, color: Colors.lightBlue), }, { 'weatherDesc': 'Snowy', 'minTemp': '5', 'maxTemp': '10', 'icon': Icon(Icons.snowing, color: Colors.lightBlueAccent), }, ]; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ // 保留你原有的顶部温度和图标Row Row( mainAxisAlignment: MainAxisAlignment.end, children: [ IconButton(icon: weatherIcon, onPressed: () {}), Text( '$sTemprature \u2103', style: TextStyle( fontWeight: FontWeight.w400, fontSize: 14.sp, color: AppTheme.grey, ), ), ], ), // 横向滚动天气预报网格 Expanded( child: GridView.builder( scrollDirection: Axis.horizontal, // 设置横向滚动 padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), itemCount: dailyWeatherList.length, // 绑定数据条数 gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 1, // 横向滚动时每行只显示1个卡片 mainAxisSpacing: 10.w, // 卡片之间的横向间距 childAspectRatio: 1.8, // 控制卡片宽高比 ), itemBuilder: (context, index) { final weather = dailyWeatherList[index]; return DailyWeatherCard( weatherDesc: weather['weatherDesc'], weatherIconInside: weather['icon'], minTemp: weather['minTemp'], maxTemp: weather['maxTemp'], ); }, ), ), ], ), ); }
核心关键点说明
- 横向滚动配置:通过
scrollDirection: Axis.horizontal开启横向滚动,crossAxisCount:1确保卡片横向排列。 - 卡片尺寸控制:固定卡片宽度或通过
childAspectRatio调整宽高比,避免卡片撑满屏幕,保证多卡片并排显示。 - 数据绑定:通过
itemCount和itemBuilder遍历API返回的5天数据,批量生成天气卡片。
内容的提问来源于stack exchange,提问作者Ashrith Shetty
相关产品推荐
相关产品推荐

