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

Flutter中如何从gRPC API为下拉按钮添加选项

实现基于gRPC服务数据的Flutter下拉菜单

第一步:完善你的gRPC数据获取方法

你当前的fetchItemsh方法有两处需要修正:

  • 把port: ----替换为实际的gRPC服务端口(比如常用的50051)
  • 必须在请求完成后关闭ClientChannel,避免资源泄漏,将客户端关闭逻辑放到finally块中

修正后的代码:

Future<GroupsStates?> fetchItemsh() async {
  final client = ClientChannel(
    LoginState.ipServerController.text,
    port: 50051, // 替换为你的实际服务端口
    options: ChannelOptions(
      credentials: ChannelCredentials.insecure(),
    ),
  );

  final stub = EngineClient(client);

  try {
    var result = await stub.groupsStatesAll(Void());
    return result;
  } catch (e) {
    print('捕获错误: $e');
    return null;
  } finally {
    await client.shutdown(); // 确保请求结束后释放客户端资源
  }
}

第二步:在Widget中实现下拉菜单逻辑

用StatefulWidget结合FutureBuilder处理异步数据的加载、错误和展示,以下是完整示例(假设你的GroupsStates proto定义包含List<GroupState> groups字段,请根据实际proto结构调整):

class GrpcDropdown extends StatefulWidget {
  const GrpcDropdown({super.key});

  @override
  State<GrpcDropdown> createState() => _GrpcDropdownState();
}

class _GrpcDropdownState extends State<GrpcDropdown> {
  GroupState? _selectedItem; // 存储选中的下拉选项

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<GroupsStates?>(
      future: fetchItemsh(),
      builder: (context, snapshot) {
        // 加载中状态
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }

        // 错误或无数据状态
        if (snapshot.hasError || snapshot.data == null) {
          return const Center(child: Text('加载数据失败'));
        }

        final itemList = snapshot.data!.groups;
        // 空数据状态
        if (itemList.isEmpty) {
          return const Center(child: Text('无可用选项'));
        }

        // 构建下拉菜单
        return DropdownButtonFormField<GroupState>(
          value: _selectedItem,
          hint: const Text('选择分组'),
          onChanged: (GroupState? newValue) {
            setState(() {
              _selectedItem = newValue;
            });
          },
          items: itemList.map((GroupState item) {
            return DropdownMenuItem<GroupState>(
              value: item,
              child: Text(item.name), // 替换为你要显示的选项文本字段,比如item.id
            );
          }).toList(),
        );
      },
    );
  }
}

关键注意事项

  • 不要直接把fetchItemsh()写在FutureBuilder的future参数里(会导致每次build都重新请求),如果需要刷新数据,建议在initState或按钮点击事件中触发
  • 根据你的ProtoBuf定义调整GroupState的字段访问逻辑,确保显示的文本是正确的业务字段
  • 生产环境请使用ChannelCredentials.secure()替代insecure(),保证通信安全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:45:49