Flutter中如何通过API获取数据实现如图所示的按钮布局?
从API取数据后实现图中的按钮布局(Flutter)
先看看图里的布局特点:
- 按钮会自动换行,宽度不够就转到下一行
- 每个按钮带圆角,有统一的内边距和样式
- 按钮上的文字是从API动态获取的标签
第一步:搞定API数据获取
假设你的API返回的是一串标签字符串列表,比如["动作", "剧情", "喜剧", "惊悚", "爱情", "恐怖"]。用http包请求接口即可,也可以先模拟数据测试。
第二步:用Wrap组件做自动换行布局
Flutter里的Wrap组件专门处理这种流式布局——子组件超出一行自动换行,完美适配动态数量的按钮需求。把API拿到的标签转换成按钮列表,塞到Wrap里就行。
完整代码示例
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class DynamicTagButtonsPage extends StatefulWidget { const DynamicTagButtonsPage({super.key}); @override State<DynamicTagButtonsPage> createState() => _DynamicTagButtonsPageState(); } class _DynamicTagButtonsPageState extends State<DynamicTagButtonsPage> { List<String> _tagList = []; bool _isLoading = true; @override void initState() { super.initState(); _getTagsFromApi(); } // 从API拉取标签数据 Future<void> _getTagsFromApi() async { try { // 替换成你的真实API地址 final response = await http.get(Uri.parse('https://your-api-url/tags')); if (response.statusCode == 200) { final List<dynamic> responseData = json.decode(response.body); setState(() { _tagList = responseData.map((tag) => tag.toString()).toList(); _isLoading = false; }); } else { throw Exception('加载标签失败'); } } catch (e) { setState(() { _isLoading = false; }); debugPrint('拉取标签出错:$e'); // 这里可以加提示框告诉用户加载失败 } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('动态标签按钮')), body: Padding( padding: const EdgeInsets.all(16.0), child: _isLoading ? const Center(child: CircularProgressIndicator()) : Wrap( spacing: 8.0, // 按钮之间的水平空隙 runSpacing: 8.0, // 两行之间的垂直空隙 children: _tagList.map((tag) { return ElevatedButton( onPressed: () { // 点击按钮的逻辑,比如筛选内容 debugPrint('点了标签:$tag'); }, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), // 圆角大小 ), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), // 想改成空心按钮的话,把ElevatedButton换成OutlinedButton即可 ), child: Text(tag), ); }).toList(), ), ), ); } }
重点细节说明
- Wrap组件:靠
spacing和runSpacing控制按钮间距,自动处理换行逻辑,不用手动计算宽度。 - 动态生成按钮:用
map方法把API返回的标签列表直接转换成按钮组件列表,高效省心。 - 按钮样式自定义:通过
styleFrom调整圆角、内边距,要是想改颜色,加对应参数就行,比如改成浅灰底黑字:
style: ElevatedButton.styleFrom( backgroundColor: Colors.grey[200], foregroundColor: Colors.black, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), ),
- 加载状态处理:拉取数据时显示进度条,避免用户界面空白无反馈。
内容的提问来源于stack exchange,提问作者Muhammad Huzaifa
相关产品推荐
相关产品推荐

