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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:18:37