最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - Children that overflow their parents don't receive tap detection - Stack Overflow

programmeradmin1浏览0评论

i am facing an issue when i use a stack and add a child that has a gesture detector and position it outside the parent widget using positioned it doesn't detect gestures anymore , if there is a fix please explain it thank you . my code for the problem :

...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)),
                      ),
                    ),
                  )
                ],
              );
            },
          ),

i am facing an issue when i use a stack and add a child that has a gesture detector and position it outside the parent widget using positioned it doesn't detect gestures anymore , if there is a fix please explain it thank you . my code for the problem :

...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)),
                      ),
                    ),
                  )
                ],
              );
            },
          ),
Share Improve this question edited Nov 21, 2024 at 6:16 DarkBee 15.6k8 gold badges72 silver badges117 bronze badges asked Nov 20, 2024 at 23:02 Lemon GrabLemon Grab 511 silver badge7 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

This behaviour is intentional. The framework hitTest goes from parent to children, and by default widget don't allow child to receive hitTest when it is outside of the parent's box.

To achieve "outside of box" gesture detection of an overflowed child. You could push the child that would overflow to the Overlay with OverlayPortal and position it with 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 Center(
          child: CompositedTransformFollower(
            link: link,
            followerAnchor: Alignment.center,
            showWhenUnlinked: false,
            child: Container(
              alignment: Alignment.center,
              height: 30,
              width: 30,
              decoration: const ShapeDecoration(shape: CircleBorder(), color: Colors.red),
              child: InkWell(
                splashColor: Colors.white,
                onTap: () {
                  setState(() {
                    count++;
                  });
                },
                child: const IgnorePointer(child: Icon(Icons.delete_forever)),
              ),
            ),
          ),
        );
      },
    );
  }
}

发布评论

评论列表(0)

  1. 暂无评论