当Flutter应用程序处于非活动状态时如何模糊处理?

3
什么是在Flutter应用程序不处于活动状态时模糊的最佳方法?类似于iOS使用相机应用程序的方式。 enter image description here

2
你应该能够检测到应用程序即将进入后台,并在此之前采取行动。我没有测试过这个,但理论上,你可以在你的应用程序上应用一个过滤视图,甚至重定向,以便多任务处理时操作系统截屏捕获模糊屏幕,而不是用户退出应用程序时所在的任何内容。 - daddygames
@daddygames 测试过了,第一次应用程序失活/暂停时不起作用(虽然应用程序会变模糊,但只是瞬间的,它会恢复正常),但是每次打开应用程序抽屉时,应用程序都会变模糊。 - esentis
@daddygames 我是通过 AppLifecycleState.inactive 来检测的。在 iOS 上可以工作,但在 Android 上无法工作。你有更好的检测方法吗? - jakub
我无法证明这里提供的功能。这篇文章可能有助于涵盖Android和iOS => 如何检查Flutter应用程序是否在前台?在每个平台的本地代码中也始终有这样的选项。 - daddygames
没错,这就是我正在检查的问题。我猜在Android上的问题是它触发得太晚了,无法及时覆盖它。 - jakub
我在这里描述了确切的问题:https://stackoverflow.com/questions/69594245/why-in-applifecyclestate-inactive-state-widgets-are-not-redrawn-every-time - jakub
2个回答

7
我在寻找相同的解决方案,这里是我实现的解决方案。 我使用了Overlay小部件来添加模糊效果,并使用AppLifecycleState来显示或隐藏它。请看下面的代码片段。 (感谢这个帖子提供的背景模糊效果代码片段)
你可以在这里找到可工作的演示链接
MaterialApp(
  ...,
  builder: (BuildContext builderContext, Widget? child) => Overlay(
    initialEntries: <OverlayEntry>[
      OverlayEntry(
        builder: (BuildContext context) => AppLifecycleOverlay(),
      )
    ],
  ),
)

class AppLifecycleOverlay extends StatefulWidget {
  const AppLifecycleOverlay({Key? key}) : super(key: key);

  @override
  State<AppLifecycleOverlay> createState() => _AppLifecycleOverlayState();
}

class _AppLifecycleOverlayState extends State<AppLifecycleOverlay>
    with WidgetsBindingObserver {
  bool shouldBlur = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      shouldBlur = state == AppLifecycleState.inactive ||
          state == AppLifecycleState.paused;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (shouldBlur) {
      return BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),
        child: Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          color: Colors.grey.shade200.withOpacity(0.5),
        ),
      );
    }

    return Container();
  }
}

0
我在MaterialApp中使用了一种替代方法,因为如果在从MaterialApp的home字段加载时直接在应用程序小部件中存在builder字段,那么我的HomeWidget将不会被构建/加载。
此外,我使用了FutureBuilder来预先获取一些设置。AppLifecycleOverlay也是一样的。
// main.dart
return MaterialApp(
      title: 'Some Awesome App',
      // ...
      home: FutureBuilder<SharedPreferences>(
        future: SharedPreferences.getInstance(),
        builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
          switch(snapshot.connectionState) {
            case ConnectionState.done:
              return Stack(
                children: [
                  HomeWidget(title: 'Some Awesome App', prefs: snapshot.data),
                  Overlay(initialEntries: [
                    OverlayEntry(builder: (BuildContext context) => const AppLifecycleOverlay()),
                  ])
                ]
              );
            default:
              return const Center(child: Text("Loading..."));
          }
        },
      ),
    );

覆盖层

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接