showAdaptiveChoose<T> function

Future<T?> showAdaptiveChoose<T>({
  1. required BuildContext context,
  2. required List<AdaptiveChooseItem<T>> items,
  3. bool showCancel = false,
})

跨平台自适应选择弹框

  • 移动端(iOS/Android):使用 CupertinoActionSheet 底部弹框
  • 桌面端(macOS/Windows/Linux)和 Web:使用 Material showMenu 下拉弹框

context 触发弹框的 BuildContext items 选项列表,每项包含 label 文本和返回值 value showCancel 是否显示取消按钮(移动端有效;桌面端点击菜单外部即可关闭)

Implementation

Future<T?> showAdaptiveChoose<T>({
  required BuildContext context,
  required List<AdaptiveChooseItem<T>> items,
  bool showCancel = false,
}) {
  if (items.isEmpty) return Future.value(null);

  if (ChatKitUtils.isDesktopOrWeb) {
    // 桌面/Web 端:使用 Material showMenu 下拉弹框
    final RenderBox? overlay =
        Overlay.of(context).context.findRenderObject() as RenderBox?;
    final Size overlaySize = overlay?.size ?? MediaQuery.of(context).size;
    // 弹出位置:屏幕中央偏右,避免遮挡左侧内容
    final double left = overlaySize.width / 2;
    final double top = overlaySize.height / 3;
    return showMenu<T>(
      context: context,
      position: RelativeRect.fromLTRB(
        left,
        top,
        overlaySize.width - left,
        overlaySize.height - top,
      ),
      items: items
          .map(
            (item) => PopupMenuItem<T>(
              value: item.value,
              child: Text(
                item.label,
                style: item.style ??
                    const TextStyle(
                      fontSize: 16,
                      color: Color(0xFF333333),
                    ),
              ),
            ),
          )
          .toList(),
    );
  } else {
    // 移动端:使用 CupertinoActionSheet 底部弹框
    return showBottomChoose<T>(
      context: context,
      actions: items
          .map(
            (item) => CupertinoActionSheetAction(
              onPressed: () {
                Navigator.pop(context, item.value);
              },
              child: Text(
                item.label,
                style: item.style ??
                    const TextStyle(
                      fontSize: 16,
                      color: Color(0xFF333333),
                    ),
              ),
            ),
          )
          .toList(),
      showCancel: showCancel,
    );
  }
}