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对象列表作为数据源,通过索引关联展示文本和对应对象:
- 替换原有字符串列表为Tenant对象列表
- 用索引记录选中位置,通过索引直接获取完整Tenant对象
- 生成Picker选项时提取Tenant的
name属性展示 - 选择回调中通过索引拿到完整对象做后续处理
修改后的完整代码
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
相关产品推荐
相关产品推荐

