插入OverlayEntry时如何阻止用户交互?

问题描述 投票:0回答:1

插入 OverlayEntry 后,我想禁用底层 Widget 上的任何用户交互,以便您只能与 OverlayEntry 交互。我怎么能做到这一点?

我已经在 Chrome 中运行了下面的示例代码。单击按钮打开 OverlayEntry 后,我只需输入 TAB 即可将焦点集中在可以输入文本的 TextField 上。

是否可以使 OverlayEntry 吸收任何按键输入,使其不会到达其下方的 Widget?或者如果失败,是否可以以某种方式完全禁用 Widget 的用户交互,直到 OverlayEntry 关闭?

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  OverlayEntry? overlayEntry;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const TextField(
              decoration: InputDecoration(
                labelText: "Input",
              ),
            ),
            TextButton(
              onPressed: () {
                overlayEntry = _newOverlayEntry();
                Overlay.of(context).insert(overlayEntry!);
              },
              child: const Text("Open Overlay"),
            ),
          ],
        ),
      ),
    );
  }

  OverlayEntry _newOverlayEntry() {
    return OverlayEntry(
      builder: (context) {
        final Size mediaSize = MediaQuery.of(context).size;

        return Container(
          color: Theme.of(context).disabledColor,
          width: mediaSize.width,
          height: mediaSize.height,
          child: Align(
            alignment: Alignment.centerRight,
            child: Container(
              width: 200,
              height: 200,
              color: Colors.green,
              child: TextButton(
                onPressed: () {
                  overlayEntry?.remove();
                  overlayEntry?.dispose();
                  overlayEntry = null;
                },
                child: const Text("Close"),
              ),
            ),
          ),
        );
      },
    );
  }
}

flutter
1个回答
0
投票

使用
showDialog
代替
OverlayEntry

OverlayEntry 并不是真正要实现您想要实现的目标。 Overlay 与 Stack 类似。您需要的是一个

Dialog
,您可以使用
showDialog
功能将其推入导航器:

class _MyHomePageState extends State<MyHomePage> {
  OverlayEntry? overlayEntry;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const TextField(
              decoration: InputDecoration(
                labelText: "Input",
              ),
            ),
            TextButton(
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (context) => Dialog(
                    insetPadding: EdgeInsets.zero,
                    alignment: Alignment.centerRight,
                    child: Container(
                      width: 200,
                      height: 200,
                      color: Colors.green,
                      child: TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: const Text("Close"),
                      ),
                    ),
                  ),
                );
              },
              child: const Text("Open Overlay"),
            ),
          ],
        ),
      ),
    );
  }
}

这会将

Dialog
推入新层,从而阻止用户与该层下方的小部件进行交互。

© www.soinside.com 2019 - 2024. All rights reserved.