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

如何为Widget声明作为参数传入的泛型对象类型?

实现Flutter通用SearchField Widget的泛型声明

要让SearchField支持返回任意类型的值,核心是利用Dart的泛型机制在Widget类中声明泛型参数,具体实现步骤如下:

1. 声明带泛型的SearchField Widget

在Widget类名后添加<T>,T就是你所说的customObjectType,它可以指代任意类型(如String、自定义对象等)。根据需求,示例实现如下:

import 'package:flutter/material.dart';

class SearchField<T> extends StatelessWidget {
  // 泛型类型的数据源列表
  final List<T> dataSource;
  // 选中项的回调,直接返回T类型的对象
  final void Function(T selectedItem) onSelected;
  // 自定义将T类型对象转为显示文本的逻辑
  final String Function(T item) itemDisplayText;

  const SearchField({
    super.key,
    required this.dataSource,
    required this.onSelected,
    required this.itemDisplayText,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 搜索输入框
        TextField(
          decoration: const InputDecoration(
            hintText: "输入关键词搜索",
            border: OutlineInputBorder(),
          ),
          // 可添加实时过滤dataSource的逻辑
        ),
        // 搜索结果列表
        Expanded(
          child: ListView.builder(
            itemCount: dataSource.length,
            itemBuilder: (context, index) {
              final T item = dataSource[index];
              return ListTile(
                title: Text(itemDisplayText(item)),
                onTap: () {
                  // 触发回调,返回选中的T类型对象
                  onSelected(item);
                },
              );
            },
          ),
        ),
      ],
    );
  }
}

2. 使用不同类型的SearchField

示例1:返回String类型

SearchField<String>(
  dataSource: ["Java", "Flutter", "Dart"],
  itemDisplayText: (item) => item,
  onSelected: (selected) {
    print("选中的编程语言:$selected"); // selected类型为String
  },
)

示例2:返回自定义对象类型

先定义自定义对象:

class User {
  final String userId;
  final String userName;

  User(this.userId, this.userName);
}

然后使用泛型为User的SearchField:

SearchField<User>(
  dataSource: [
    User("u001", "张三"),
    User("u002", "李四"),
  ],
  itemDisplayText: (user) => user.userName,
  onSelected: (selectedUser) {
    print("选中用户ID:${selectedUser.userId},姓名:${selectedUser.userName}");
    // selectedUser类型为User,可直接调用其属性
  },
)

3. 可选:给泛型添加约束

如果需要限制T必须是某个类的子类(比如所有数据模型都继承自BaseModel),可以这样声明泛型:

class SearchField<T extends BaseModel> extends StatelessWidget {
  // ... 其余代码不变
}

这样就能确保传入的T都符合BaseModel的规范,避免类型误用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:27:46