超出其父母的 Flutter 子项不会收到点击检测

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

当我使用堆栈并添加一个具有手势检测器的子部件并使用定位将其放置在父部件之外时,我遇到了一个问题,它不再检测手势,如果有修复,请解释一下 谢谢 。 我的问题代码:

...List<Widget>.generate(
            images.length,
            (index) {
              return Stack(
                clipBehavior: Clip.none,
                children: [
                  Container(
                    height: deviceWidth / 3.5,
                    width: deviceWidth / 3.5,
                    clipBehavior: Clip.antiAlias,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10)),
                    child: GestureDetector(
                      onLongPressStart: (details) {},
                      onTap: () async {
                        var imageFile = await pickImage();
                        if (imageFile != null) {
                          images[index] = makeImage(
                              isPlaceholder: false,
                              imageData: await imageFile.readAsBytes());
                          setState(
                            () {},
                          );
                        }
                      },
                      child: images[index],
                    ),
                  ),
                  Positioned(
                    left: -10,
                    top: -15,
                    child: Container(
                      alignment: Alignment.center,
                      height: 30,
                      width: 30,
                      decoration: const ShapeDecoration(
                          shape: CircleBorder(), color: Colors.red),
                      child: InkWell(
                        splashColor: Colors.white,
                        onTap: () {
                          images.remove(images[index]);
                          setState(() {});
                        },
                        child: const IgnorePointer(
                            child: Icon(Icons.delete_forever)),
                      ),
                    ),
                  )
                ],
              );
            },
          ),
flutter dart
1个回答
0
投票

这种行为是故意的。框架 hitTest 从父级传递到子级,默认情况下,当子级在父级框之外时,小部件不允许子级接收 hitTest

要实现这种“开箱即用”的效果,您可以将

OverlyPortal
LayerLink

一起使用
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('LayerLink'),
        ),
        body: const Center(child: Home()),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return const Padding(
      padding: EdgeInsets.all(20.0),
      child: Wrap(
        spacing: 10.0,
        runSpacing: 10.0,
        children: [
          MyImage(color: Colors.blue),
          MyImage(color: Colors.green),
          MyImage(color: Colors.yellow),
          MyImage(color: Colors.orange),
          MyImage(color: Colors.purple),
          MyImage(color: Colors.red),
          MyImage(color: Colors.pink),
          MyImage(color: Colors.teal),
          MyImage(color: Colors.brown),
          MyImage(color: Colors.grey),
        ],
      ),
    );
  }
}

class MyImage extends StatefulWidget {
  const MyImage({super.key, required this.color});
  final Color color;

  @override
  State<MyImage> createState() => _MyImageState();
}

class _MyImageState extends State<MyImage> {
  int count = 0;
  final controller = OverlayPortalController();
  final link = LayerLink();

  @override
  void initState() {
    super.initState();
    controller.show();
  }

  @override
  Widget build(BuildContext context) {
    return OverlayPortal(
      controller: controller,
      child: CompositedTransformTarget(
        link: link,
        child: Container(
          color: widget.color,
          height: 100,
          width: 100,
          alignment: Alignment.center,
          child: Text(
            "$count",
            style: const TextStyle(fontSize: 30),
          ),
        ),
      ),
      overlayChildBuilder: (context) {
        return CompositedTransformFollower(
          link: link,
          followerAnchor: Alignment.center,
          showWhenUnlinked: false,
          child: Center(
            child: IconButton(
              style: ButtonStyle(
                backgroundColor: WidgetStatePropertyAll(widget.color),
                side: const WidgetStatePropertyAll(BorderSide(color: Colors.black)),
              ),
              onPressed: () {
                setState(() {
                  count++;
                });
              },
              icon: const Icon(
                Icons.add,
              ),
            ),
          ),
        );
      },
    );
  }
}

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