show<T> static method

Future<MySelectorResult<T>> show<T>({
  1. required BuildContext triggerContext,
  2. required List<MySelectorItem<T>> items,
  3. T? currentValue,
  4. MySelectorClearOption? clearOption,
  5. bool allowReselect = false,
  6. bool? showPanelAbove,
  7. bool showSearch = false,
  8. String searchHint = '搜索…',
  9. bool searchFilter(
    1. MySelectorItem<T> item,
    2. String query
    )?,
  10. Widget itemBuilder(
    1. BuildContext context,
    2. MySelectorItem<T> item,
    3. bool isSelected
    )?,
  11. Widget footerBuilder(
    1. BuildContext context,
    2. VoidCallback dismiss
    )?,
  12. MySelectorStyle? style,
})

弹出选择器面板,返回 MySelectorResult 告知调用方用户的操作意图。

Implementation

static Future<MySelectorResult<T>> show<T>({
  required BuildContext triggerContext,
  required List<MySelectorItem<T>> items,
  T? currentValue,
  // 清除 & 复选取消
  MySelectorClearOption? clearOption,
  bool allowReselect = false,
  // 弹出方向:null = 自动(根据可用空间判断),true = 强制上方,false = 强制下方
  bool? showPanelAbove,
  // 搜索
  bool showSearch = false,
  String searchHint = '搜索…',
  bool Function(MySelectorItem<T> item, String query)? searchFilter,
  // 自定义渲染
  Widget Function(
    BuildContext context,
    MySelectorItem<T> item,
    bool isSelected,
  )? itemBuilder,
  Widget Function(BuildContext context, VoidCallback dismiss)? footerBuilder,
  // 样式
  MySelectorStyle? style,
}) async {
  assert(items.isNotEmpty, 'items 不能为空');

  final effectiveStyle = style ?? MySelectorStyle();
  final completer = Completer<MySelectorResult<T>>();

  final renderBox = triggerContext.findRenderObject() as RenderBox;
  final overlayState = Overlay.of(triggerContext, rootOverlay: true);

  late OverlayEntry entry;

  void dismiss(MySelectorResult<T> result) {
    entry.remove();
    if (!completer.isCompleted) {
      completer.complete(result);
    }
  }

  entry = OverlayEntry(
    builder: (_) => _SelectorOverlay<T>(
      renderBox: renderBox,
      overlayState: overlayState,
      items: items,
      currentValue: currentValue,
      clearOption: clearOption,
      allowReselect: allowReselect,
      showPanelAbove: showPanelAbove,
      showSearch: showSearch,
      searchHint: searchHint,
      searchFilter: searchFilter,
      itemBuilder: itemBuilder,
      footerBuilder: footerBuilder,
      style: effectiveStyle,
      onSelected: (item) =>
          dismiss(MySelectorValueChanged(item.value, item: item)),
      onCleared: () => dismiss(MySelectorValueChanged(null)),
      onDismiss: () => dismiss(MySelectorDismissed()),
    ),
  );

  overlayState.insert(entry);
  return completer.future;
}