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

Flutter中如何将Tenant对象列表传入CupertinoPicker并获取选中对象

解决CupertinoPicker处理Tenant对象列表的问题

我需要将Tenant对象列表传入CupertinoPicker组件,但该组件目前仅支持展示字符串列表。想实现两个目标:

  • 提取每个Tenant对象的name属性作为Picker的展示文本
  • 用户选择名称后,能获取到对应的完整Tenant对象

原有字符串列表实现代码

import 'package:flutter/cupertino.dart';

class MainCupertinoPicker extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _StateCupertinoPicker();
  }

}

class _StateCupertinoPicker extends State<MainCupertinoPicker>{

  int _selectedFruit = 0;
  void _showDialog(Widget child, {required Text}) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 216,
        padding: const EdgeInsets.only(top: 6.0),
        margin: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        color: CupertinoColors.systemBackground.resolveFrom(context),
        child: SafeArea(
          top: false,
          child: child,
        ),
      )
    );
  }

  double _kItemExtent = 32.0;
  List<String> _fruitNames = <String>[
    'Crato',
    'Juazeiro',
    'Fortaleza'
  ];

  @override
  Widget build(BuildContext context) {
    return Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'Selecione o municipio: ',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold
                ),
              ),
              CupertinoButton(
                padding: EdgeInsets.zero,
                onPressed: () => _showDialog(
                  CupertinoPicker(
                    magnification: 1.22,
                    squeeze: 1.2,
                    useMagnifier: true,
                    itemExtent: _kItemExtent,
                    onSelectedItemChanged: (int selectedItem) {
                      setState(() {
                        _selectedFruit = selectedItem;
                        print(_selectedFruit);
                      });
                    },
                    children:
                        List<Widget>.generate(_fruitNames.length, (int index) {
                      return Center(
                        child: Text(
                          _fruitNames[index],
                        ),
                      );
                    }),
                  ), Text: null,
                ),
                child: Text(
                  _fruitNames[_selectedFruit],
                  style: const TextStyle(
                    fontSize: 22.0,
                  ),
                ),
              ),
            ],
          ),
    );
  }
}

Tenant类定义

class Tenant {
  int id;
  String name;
  String siafi;
  String url;
  String username;
  String password;
  String driverClassName;
  bool initialize;

  Tenant({required this.id, required this.name, required this.siafi, required this.url, required this.driverClassName, required this.username, required this.initialize, required this.password});

  factory Tenant.fromJson(Map<String, dynamic> json){
    return Tenant(
      id: json["id"], 
      name: json["name"], 
      siafi: json["siafi"], 
      url: json["url"], 
      driverClassName: json["driverClassName"], 
      username: json["username"], 
      initialize: json["initialize"], 
      password: json["password"]
    );
  }
}

解决方案

修改思路

核心是保留Tenant对象列表作为数据源,通过索引关联展示文本和对应对象:

  1. 替换原有字符串列表为Tenant对象列表
  2. 用索引记录选中位置,通过索引直接获取完整Tenant对象
  3. 生成Picker选项时提取Tenant的name属性展示
  4. 选择回调中通过索引拿到完整对象做后续处理

修改后的完整代码

import 'package:flutter/cupertino.dart';

class MainCupertinoPicker extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _StateCupertinoPicker();
  }
}

class _StateCupertinoPicker extends State<MainCupertinoPicker>{
  // 替换为Tenant对象数据源(可从接口/本地数据填充)
  List<Tenant> _tenants = <Tenant>[
    Tenant(id: 1, name: 'Crato', siafi: 'xxx', url: 'xxx', driverClassName: 'xxx', username: 'xxx', initialize: true, password: 'xxx'),
    Tenant(id: 2, name: 'Juazeiro', siafi: 'xxx', url: 'xxx', driverClassName: 'xxx', username: 'xxx', initialize: true, password: 'xxx'),
    Tenant(id: 3, name: 'Fortaleza', siafi: 'xxx', url: 'xxx', driverClassName: 'xxx', username: 'xxx', initialize: true, password: 'xxx'),
  ];
  int _selectedIndex = 0;

  void _showDialog(Widget child) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 216,
        padding: const EdgeInsets.only(top: 6.0),
        margin: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        color: CupertinoColors.systemBackground.resolveFrom(context),
        child: SafeArea(
          top: false,
          child: child,
        ),
      )
    );
  }

  double _kItemExtent = 32.0;

  @override
  Widget build(BuildContext context) {
    // 获取当前选中的完整Tenant对象
    Tenant selectedTenant = _tenants[_selectedIndex];

    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          const Text(
            'Selecione o municipio: ',
            style: TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.bold
            ),
          ),
          CupertinoButton(
            padding: EdgeInsets.zero,
            onPressed: () => _showDialog(
              CupertinoPicker(
                magnification: 1.22,
                squeeze: 1.2,
                useMagnifier: true,
                itemExtent: _kItemExtent,
                onSelectedItemChanged: (int selectedItem) {
                  setState(() {
                    _selectedIndex = selectedItem;
                    // 直接获取选中的完整Tenant对象
                    Tenant selected = _tenants[selectedItem];
                    print('选中租户ID: ${selected.id}, 名称: ${selected.name}');
                  });
                },
                children: List<Widget>.generate(_tenants.length, (int index) {
                  // 提取Tenant的name属性作为展示文本
                  return Center(
                    child: Text(
                      _tenants[index].name,
                    ),
                  );
                }),
              ),
            ),
            // 展示选中租户的名称
            child: Text(
              selectedTenant.name,
              style: const TextStyle(
                fontSize: 22.0,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class Tenant {
  int id;
  String name;
  String siafi;
  String url;
  String username;
  String password;
  String driverClassName;
  bool initialize;

  Tenant({required this.id, required this.name, required this.siafi, required this.url, required this.driverClassName, required this.username, required this.initialize, required this.password});

  factory Tenant.fromJson(Map<String, dynamic> json){
    return Tenant(
      id: json["id"], 
      name: json["name"], 
      siafi: json["siafi"], 
      url: json["url"], 
      driverClassName: json["driverClassName"], 
      username: json["username"], 
      initialize: json["initialize"], 
      password: json["password"]
    );
  }
}

关键修改点

  • 数据源替换:将字符串列表_fruitNames改为Tenant对象列表_tenants,可根据业务场景从接口或本地存储填充数据
  • 选中状态管理:用_selectedIndex记录选中位置,通过索引直接从_tenants中获取完整对象
  • Picker选项生成:遍历Tenant列表,每个选项展示tenant.name属性
  • 选择回调处理:在onSelectedItemChanged中通过索引拿到对应Tenant对象,可直接使用其所有属性(如id、url等)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:35:36