flutter_boost icon indicating copy to clipboard operation
flutter_boost copied to clipboard

[Bug]: 从iOS原生端模态弹出Flutter页面,Flutter页面设置透明,结果Flutter页面呈现白色全屏

Open applebest opened this issue 1 year ago • 13 comments

请描述遇到的问题,以及您所期望的正确的结果

iOS原生端:


       let vc:FBFlutterViewContainer = FlutterVC()
        vc.setName(options.pageName, uniqueId: options.uniqueId, params: options.arguments,opaque: options.opaque)
        vc.view.backgroundColor = .clear
        self.present(vc, animated: true, completion: nil)

Flutter端路由代理:


   RouterPath.memberAlert: (settings, uniqueId) {
 

      return ModalBottomSheetRoute(
        settings: settings,
        enableDrag: true,
        isDismissible: true,
        backgroundColor: Colors.transparent,
        modalBarrierColor: Colors.transparent,
        builder: (context) {
          // return const MemberAlert();

          return AnimatedPadding(
              padding: MediaQuery.of(context).viewInsets,
              // padding: EdgeInsets.zero,
              duration: const Duration(milliseconds: 100),
              curve: Curves.decelerate,
              child: const MemberAlert());
        },
        isScrollControlled: false,
      );
    }

Widget


const MemberAlert({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Align(
        alignment: Alignment.bottomCenter,
        child: ClickWidget(
          onTap: () => Nav.unfocus(),
          child: ClipRRect(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(12.r),
                topRight: Radius.circular(12.r)),
            child: Container(
              height: 280.h,
              padding: EdgeInsets.symmetric(horizontal: 24.h),
              color: Colors.white,
              // width: 1.sw,
              child: Column(
                children: [
                  Container(
                    margin: EdgeInsets.only(top: 8.h),
                    width: 28.w,
                    height: 4.h,
                    decoration: BoxDecoration(
                        color: rgba(221, 222, 226, 1),
                        borderRadius: BorderRadius.circular(2.r)),
                  ),
                  Box.gapV(41.h),
                  TextWidget(
                    MemberKeys.todaysFreeAlChatUsedUp.tr,
                    fontSize: 28.sp,
                    textAlign: TextAlign.center,
                    color: rgba(1, 1, 1, 1),
                    style: TextWidgetStyle.bold,
                  ),
                  Box.gapV(12.h),
                  TextWidget(
                    MemberKeys.upgradeForUnlimitedAlChat.tr,
                    textAlign: TextAlign.center,
                    fontSize: 14.sp,
                    color: rgba(1, 1, 1, 1),
                    style: TextWidgetStyle.regular,
                  ),
                  Box.gapV(24.h),
                  ClickableContainer(
                    onTap: () {
                      Nav.pushReplacement(RouterPath.member);
                      // Navigator.of(context).pop();
                      // Nav.push(RouterPath.member);
                    },
                    alignment: Alignment.center,
                    // width: 1.sw,
                    height: 44.h,
                    // padding: EdgeInsets,
                    borderRadius: BorderRadius.circular(12.r),
                    color: rgba(42, 112, 255, 1),
                    child: TextWidget(
                      MemberKeys.upgrade.tr,
                      fontSize: 16.sp,
                      color: Colors.white,
                      style: TextWidgetStyle.bold,
                    ),
                  ),
                  Box.gapV(30.h),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }


xCode , Debug View Hierarchy打印

image 发现FlutterView背景是UIExtendedGrayColorSpace

希望能在现有的页面之上,弹出一个透明的提示框

请说明如何操作会遇到上述问题

No response

在下面填入关键复现代码

复现的平台

iOS

Flutter SDK版本

3.22.0

FlutterBoost版本

master分支

是否延迟初始化FlutterBoost

No

解决方案

applebest avatar Nov 21 '24 06:11 applebest

+1 同样可复现

boost: 4.6.5/5.0.2 flutter sdk: 3.24.5

@joechan-cq

yaotiancheng-ola avatar Feb 27 '25 07:02 yaotiancheng-ola

+1 同样可复现

boost: 4.6.5 flutter sdk: 3.24.2

rgmyyw avatar Mar 11 '25 07:03 rgmyyw

opaque参数给false了吗? 类似 BoostNavigator.instance.push("study_task_guide", arguments: {"animated": false}, opaque: false, withContainer: true);

forping avatar Mar 26 '25 06:03 forping

opaque参数给false了吗? 类似 BoostNavigator.instance.push("study_task_guide", arguments: {"animated": false}, opaque: false, withContainer: true);

都试了,无效

applebest avatar Mar 26 '25 16:03 applebest

宝~, 这个问题能不能解决一下~

xd-jeff avatar Apr 01 '25 13:04 xd-jeff

宝~, 这个问题能不能解决一下~

很多原生需求,在现有原生页面的VC之上 模态推出一个和flutter一样的页面结构 - - 我想复用。。。。

applebest avatar May 07 '25 08:05 applebest

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry
class CustomContainerOverlayEntry extends ContainerOverlayEntry {
  CustomContainerOverlayEntry(super.container) {
    opaque = false; // 重点是这里
  }
}
  1. 设置自定义的overlay
void main() async {
    CustomFlutterBinding();
    ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container);
}
  1. 使用 ModalBottomSheetRoute 弹出dialog

@applebest @xd-jeff 我这边用这种方式处理的这个问题

yaotiancheng-ola avatar Jun 04 '25 09:06 yaotiancheng-ola

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay

void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog

@applebest @xd-jeff 我这边用这种方式处理的这个问题

能贴一下flutter_boost 路由里面的弹出代码吗 ?

applebest avatar Jun 06 '25 04:06 applebest

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay

void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog

@applebest @xd-jeff 我这边用这种方式处理的这个问题

ContainerOverlayEntry 这是一个自定的类把 ,这个类继承的OverlayEntry 么

applebest avatar Jun 06 '25 05:06 applebest

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog @applebest @xd-jeff 我这边用这种方式处理的这个问题

ContainerOverlayEntry 这是一个自定的类把 ,这个类继承的OverlayEntry 么

直接继承 ContainerOverlayEntryOverlayEntry 并没有暴露出来

yaotiancheng-ola avatar Jun 10 '25 04:06 yaotiancheng-ola

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog @applebest @xd-jeff 我这边用这种方式处理的这个问题

能贴一下flutter_boost 路由里面的弹出代码吗 ?


class DialogFatherWidget extends StatelessWidget {
  final Widget widget;

  const DialogFatherWidget(this.widget, {super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: GestureDetector(
            onTap: () {
              Navigator.of(context).pop();
            },
            child: Container(
              color: Colors.transparent,
            ),
          ),
        ),
        widget,
      ],
    );
  }
}

FlutterBoostRouteFactory? router(RouteSettings settings) {

    /// NOTE:这里需要注意!!!,
    /// 1. 调用dialog跳转必须由Boost navigator api调用,否则会变成push动画(左->右)打开页面
    ///   a. 由iOS平台层通过FlutterBoost.instance().open(boostOptions)
    ///   b. 由flutter通过BoostNavigator.instance.push(PageRouter.testDialog, arguments: {"isPresent": true}, withContainer: true);
    /// 2. 不能存在多个命名路由dialog,否则会导致第二个页面弹不出来
    Widget? widget = dialogWidget(settings.name ?? '', getParams(settings));

    if (widget != null) {
      return (RouteSettings settings, bool isContainerPage, String? uniqueId) {
        return ModalBottomSheetRoute(
            settings: settings,
            builder: (context) {
              /// 这里会套一层widget,用来处理点击空白处关闭页面,ModalBottomSheetRoute原来有这个功能的,但不知道什么原因失效了,后续再排查吧,临时先用这种解决方案
              return DialogFatherWidget(widget!);
            },
            isScrollControlled: true,
            backgroundColor: Colors.transparent,
            modalBarrierColor: Colors.transparent);
      };
    }
}

yaotiancheng-ola avatar Jun 10 '25 04:06 yaotiancheng-ola

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog @applebest @xd-jeff 我这边用这种方式处理的这个问题

能贴一下flutter_boost 路由里面的弹出代码吗 ?

class DialogFatherWidget extends StatelessWidget { final Widget widget;

const DialogFatherWidget(this.widget, {super.key});

@override Widget build(BuildContext context) { return Column( children: [ Expanded( child: GestureDetector( onTap: () { Navigator.of(context).pop(); }, child: Container( color: Colors.transparent, ), ), ), widget, ], ); } }

FlutterBoostRouteFactory? router(RouteSettings settings) {

/// NOTE:这里需要注意!!!,
/// 1. 调用dialog跳转必须由Boost navigator api调用,否则会变成push动画(左->右)打开页面
///   a. 由iOS平台层通过FlutterBoost.instance().open(boostOptions)
///   b. 由flutter通过BoostNavigator.instance.push(PageRouter.testDialog, arguments: {"isPresent": true}, withContainer: true);
/// 2. 不能存在多个命名路由dialog,否则会导致第二个页面弹不出来
Widget? widget = dialogWidget(settings.name ?? '', getParams(settings));

if (widget != null) {
  return (RouteSettings settings, bool isContainerPage, String? uniqueId) {
    return ModalBottomSheetRoute(
        settings: settings,
        builder: (context) {
          /// 这里会套一层widget,用来处理点击空白处关闭页面,ModalBottomSheetRoute原来有这个功能的,但不知道什么原因失效了,后续再排查吧,临时先用这种解决方案
          return DialogFatherWidget(widget!);
        },
        isScrollControlled: true,
        backgroundColor: Colors.transparent,
        modalBarrierColor: Colors.transparent);
  };
}

}

感谢🙏🏻

applebest avatar Jun 10 '25 05:06 applebest

  1. 自定义一个 CustomContainerOverlayEntry 继承于 ContainerOverlayEntry

class CustomContainerOverlayEntry extends ContainerOverlayEntry { CustomContainerOverlayEntry(super.container) { opaque = false; // 重点是这里 } } 2. 设置自定义的overlay void main() async { CustomFlutterBinding(); ContainerOverlay.overlayEntryFactory = (container) => CustomContainerOverlayEntry(container); } 3. 使用 ModalBottomSheetRoute 弹出dialog @applebest @xd-jeff 我这边用这种方式处理的这个问题

能贴一下flutter_boost 路由里面的弹出代码吗 ?

class DialogFatherWidget extends StatelessWidget { final Widget widget; const DialogFatherWidget(this.widget, {super.key}); @OverRide Widget build(BuildContext context) { return Column( children: [ Expanded( child: GestureDetector( onTap: () { Navigator.of(context).pop(); }, child: Container( color: Colors.transparent, ), ), ), widget, ], ); } } FlutterBoostRouteFactory? router(RouteSettings settings) {

/// NOTE:这里需要注意!!!,
/// 1. 调用dialog跳转必须由Boost navigator api调用,否则会变成push动画(左->右)打开页面
///   a. 由iOS平台层通过FlutterBoost.instance().open(boostOptions)
///   b. 由flutter通过BoostNavigator.instance.push(PageRouter.testDialog, arguments: {"isPresent": true}, withContainer: true);
/// 2. 不能存在多个命名路由dialog,否则会导致第二个页面弹不出来
Widget? widget = dialogWidget(settings.name ?? '', getParams(settings));

if (widget != null) {
  return (RouteSettings settings, bool isContainerPage, String? uniqueId) {
    return ModalBottomSheetRoute(
        settings: settings,
        builder: (context) {
          /// 这里会套一层widget,用来处理点击空白处关闭页面,ModalBottomSheetRoute原来有这个功能的,但不知道什么原因失效了,后续再排查吧,临时先用这种解决方案
          return DialogFatherWidget(widget!);
        },
        isScrollControlled: true,
        backgroundColor: Colors.transparent,
        modalBarrierColor: Colors.transparent);
  };
}

}

感谢🙏🏻

这个有用吗?设置后没效果

xntop avatar Aug 15 '25 10:08 xntop