flutter_bottom_sheet_pickers 0.1.0 copy "flutter_bottom_sheet_pickers: ^0.1.0" to clipboard
flutter_bottom_sheet_pickers: ^0.1.0 copied to clipboard

Customizable Flutter bottom sheet pickers for single, multiple, searchable, lazy loaded, and cascade selection.

flutter_bottom_sheet_pickers #

pub package pub points GitHub Issues GitHub Forks GitHub Stars GitHub License

flutter_bottom_sheet_pickers 是一个面向 Flutter 的底部弹窗选择器集合,当前支持单选、多选、搜索、分页懒加载、最多三级级联选择。

它适合需要快速完成表单选择、筛选条件、地区/门店/组织层级选择、远程分页数据选择等场景的 Flutter 应用。包本身只依赖 Flutter SDK,API 采用链式 builder,通常一段代码即可打开 picker 并拿到返回值。

功能特性 #

  • 单选选择器
  • 多选选择器
  • 搜索选择器
  • 分页懒加载选择器,适合远程数据源
  • 最多三级级联选择器,支持单选和多选
  • 支持禁用部分选项、允许空选择确认、自定义 option row
  • 底部弹窗布局,内置 cancel、reset、confirm 操作
  • 点击弹窗外区域会关闭弹窗,返回值与点击 cancel 一致
  • 支持主题色和按钮圆角配置
  • 内置英文、简体中文、繁体中文、泰文、缅甸语、巴西葡萄牙语、加拿大法语、意大利语、西班牙语文案

语言: 中文 | English

平台支持 #

Android iOS MacOS Web Linux Windows

依赖要求 #

  • Flutter >=3.13.0 <4.0.0
  • Dart >=3.1.0 <4.0.0

安装 #

pubspec.yaml 中添加:

dependencies:
  flutter_bottom_sheet_pickers: ^0.1.0

导入:

import 'package:flutter_bottom_sheet_pickers/flutter_bottom_sheet_pickers.dart';

API 速查 #

入口 用途 返回值
BottomSheetPickers.single<T>(context) 普通单选、搜索单选、懒加载单选 Future<T?>
BottomSheetPickers.multiple<T>(context) 普通多选、搜索多选、懒加载多选 Future<List<T>?>
BottomSheetPickers.cascade(context) 最多三级级联单选 Future<CascadeSelection?>
BottomSheetPickers.cascade(context).multiple() 最多三级级联多选 Future<List<CascadeSelection>?>
BottomSheetPickers.setLocalizations(...) 设置全局 picker 文案 void
BottomPickerConfig(...) 对局部 widget subtree 覆盖 picker 文案 Widget

快速上手 #

单选 #

final selected = await BottomSheetPickers.single<String>(
  context,
  title: "选择水果",
).options(
  ["Apple", "Orange", "Banana"],
  initialValue: "Apple",
).show();

多选 #

final List<String>? selected = await BottomSheetPickers.multiple<String>(
  context,
  title: "选择标签",
).options(
  ["New", "Popular", "Recommended"],
  initialValue: ["New"],
).show();

搜索 #

final selected = await BottomSheetPickers.single<String>(
  context,
  title: "选择城市",
).options(cities)
    .searchSupported(placeholder: "搜索城市")
    .show();

分页懒加载 #

final future = (params) async {
  final pageIndex = params["page_index"] as int;
  final pageSize = params["page_size"] as int;
  final keyword = params["keyword"] as String?;
  return loadStores(pageIndex: pageIndex, pageSize: pageSize, keyword: keyword);
};
final selected = await BottomSheetPickers.single<String>(
  context,
  title: "选择门店",
).lazyLoad(
  parameters: {"country": "TH"},
  lazyRequestFuture: future,
).show();

lazyRequestFuture 会收到 page_indexpage_sizekeyword 参数,并需要返回当前页的 List<T>。如果打开了搜索,keyword 会随搜索关键字一起传入。

级联选择 #

final CascadeSelection? selected = await BottomSheetPickers.cascade(
  context,
  title: "选择地区",
).options(
  [
    CascadeOption(
      id: "province_a",
      label: "Province A",
      children: [
        CascadeOption(
          id: "city_a",
          label: "City A",
          children: [
            CascadeOption(id: "town_a", label: "Town A"),
          ],
        ),
      ],
    ),
  ],
).initialValue(CascadeSelection.byIds("province_a", "city_a", "town_a"))
    .cascadeAllItemSupported()
    .show();

级联多选 #

final List<CascadeSelection>? selected = await BottomSheetPickers.cascade(
  context,
  title: "选择多个地区",
).options(options)
    .multiple()
    .initialValues([
      CascadeSelection.byIds("province_a", "city_a", "town_a"),
    ])
    .cascadeAllItemSupported(allItemLabel: "全部")
    .show();

级联选择器支持 List<CascadeOption>、map-like list 和 adjacency map 数据。map-like list 示例:

final options = [
  {
    "id": 1,
    "label": "Province A",
    "value": "province-a",
    "children": [
      {
        "id": 11,
        "label": "City A",
        "children": [
          {"id": 111, "label": "Town A"}
        ]
      }
    ]
  }
];

解析 label 时会按 labelvaluenameid 顺序取值。

也可以传入 adjacency map。每个 key 表示父级 id,对应的 list 表示子节点:

final adjacencyOptions = {
  null: [
    {"id": "province_a", "label": "Province A"}
  ],
  "province_a": [
    {"id": "city_a", "label": "City A"}
  ],
  "city_a": [
    {"id": "town_a", "label": "Town A"}
  ],
};

CascadeSelection.byIds(...) 可用于设置初始值。picker 会用 id 在 options 中查找对应节点,最终返回包含真实 CascadeOption 对象的 CascadeSelection

禁用选项和空选择 #

final selected = await BottomSheetPickers.multiple<String>(
  context,
  title: "选择标签",
).options(
  tags,
  disabledValues: ["Archived"],
).allowNoSelection()
    .show();

disabledValues 与 option 自身值比较;级联 picker 中可以传入需要禁用的 option id 或 value。allowNoSelection() 允许用户未选择内容时点击 confirm。

主题 #

传入 primaryColor 后,按钮背景色、按钮边框色、选中颜色和选中背景色会自动派生。buttonBorderRadius 用于配置底部 action 按钮圆角,默认是 BorderRadius.circular(24)

BottomSheetPickers.single<String>(
  context,
  title: "选择水果",
  themeData: const BottomPickerTheme(
    primaryColor: Color(0xFF1677FF),
    buttonBorderRadius: BorderRadius.all(Radius.circular(12)),
  ),
).show();

返回值和取消行为 #

  • 单选 confirm 返回 T?
  • 多选 confirm 返回 List<T>?
  • 级联单选 confirm 返回 CascadeSelection?
  • 级联多选 confirm 返回 List<CascadeSelection>?
  • 点击 cancel、点击弹窗外区域、或系统返回关闭弹窗时返回 null
  • reset 是独立行为:多选返回空列表,级联单选返回 reset selection

多语言 #

包内内置基础文案,不使用 delegate。没有配置时,会根据当前 Flutter Locale 自动选择内置语言;不识别时会使用系统语言,仍不支持则默认英文。

当前内置语言:

BottomPickerLocalizations.en
BottomPickerLocalizations.zh
BottomPickerLocalizations.zhHant
BottomPickerLocalizations.th
BottomPickerLocalizations.my
BottomPickerLocalizations.ptBR
BottomPickerLocalizations.frCA
BottomPickerLocalizations.it
BottomPickerLocalizations.es
BottomSheetPickers.single<String>(context).options(items).show();

作为工具类弹窗使用时,推荐在 app 初始化或语言切换后设置一次全局默认文案:

BottomSheetPickers.setLocalizations(
  localizations: BottomPickerLocalizations.byLocale(currentLocale),
);

业务语言切换时再次设置即可,新打开的 picker 会同步使用新文案:

void changeLocale(Locale locale) {
  BottomSheetPickers.setLocalizations(
    localizations: BottomPickerLocalizations.byLocale(locale),
  );
}

如果业务有自己的多语言扩展,可以配置动态 builder:

BottomSheetPickers.setLocalizations(
  builder: (context) => BottomPickerLocalizations(
    cancel: context.i18n("cancel"),
    reset: context.i18n("reset"),
    confirm: context.i18n("confirm"),
  ),
);

未配置的字段会继续按当前 locale 使用内置文案。

如需局部覆盖某个页面或区域,也可以使用 BottomPickerConfig

BottomPickerConfig(
  localizations: BottomPickerLocalizations.zh,
  child: PageContent(),
)

其他信息 #

  • 示例应用在 example/ 目录。
  • 发布前建议运行 flutter analyzeflutter testflutter pub publish --dry-run
  • 如有问题或功能建议,欢迎提交 Issue。
1
likes
0
points
229
downloads

Publisher

unverified uploader

Weekly Downloads

Customizable Flutter bottom sheet pickers for single, multiple, searchable, lazy loaded, and cascade selection.

Repository (GitHub)
View/report issues

Topics

#picker #bottom-sheet #cascade-picker #flutter-picker #selection

License

unknown (license)

Dependencies

flutter

More

Packages that depend on flutter_bottom_sheet_pickers