0

我有一个包裹在 GestureDetector 内的容器 A,它向下点击可将背景颜色更改为黄色,向上点击可将颜色恢复为红色。当容器 A 被点击时,颜色会变成这样(红色 -> 黄色 -> 红色)。但是如果这个容器 A 用另一个空的容器 B 包裹在一个 PageView 中,点击容器 A 只会显示点击颜色(红色),只有当我长按容器 A 时才会显示点击颜色(黄色),这预计不会。我试图从 PageView 中删除容器 B,然后容器 A 的颜色变化将正确显示(红色 -> 黄色 -> 红色)。请帮我弄清楚,谢谢。这是示例代码。

class PageViewDemo extends StatefulWidget {
  @override
  _PageViewDemoState createState() => _PageViewDemoState();
}

class _PageViewDemoState extends State<PageViewDemo>
    with SingleTickerProviderStateMixin {
  PageController _pageController;
  TabController _tabController;

  static var pageOneColor;
  static var isTapped;

  @override
  void initState() {
    super.initState();
    pageOneColor = Colors.red;
    isTapped = false;
    _pageController = PageController();
    _tabController = TabController(vsync: this, length: 2);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(
              top: 40.0,
            ),
            child: TabPageSelector(
              controller: _tabController,
              color: Colors.transparent,
              selectedColor: Colors.blue,
            ),
          ),
          Container(
            width: MediaQuery.of(context).size.width,
            height: 400,
            child: PageView(
              controller: _pageController,
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                Container(
                  color: Colors.greenAccent,
                  child: Container(
                    padding: EdgeInsets.all(50),
                    decoration: BoxDecoration(
                      border: Border.all(
                        width: 3,
                        color: Colors.black,
                      ),
                    ),
                    height: 100,
                    width: 100,
                    child: RawGestureDetector(
                      gestures: <Type, GestureRecognizerFactory>{
                        CustomButtonGestureRecognizer:
                            GestureRecognizerFactoryWithHandlers<
                                CustomButtonGestureRecognizer>(
                          () => CustomButtonGestureRecognizer(
                            onTapDown: _onTapDown,
                            onTapUp: _onTapUp,
                            onTapCancel: _onTapCancel,
                          ),
                          (CustomButtonGestureRecognizer instance) {},
                        ),
                      },
                      child: Container(
                        color: pageOneColor,
                        child: Center(
                          child: Text('Container A'),
                        ),
                      ),
                    ),
//                    child: GestureDetector(
//                      onTapDown: (detail) {
//                        /// TapDown Color isn't shown if 'Container B' is added to PageView
//                        print(detail);
//                        setState(() {
//                          isTapped = true;
//                          pageOneColor = Colors.yellow;
//                        });
//                      },
//                      onTapUp: (detail) {
//                        print(detail);
//                        setState(() {
//                          isTapped = false;
//                          pageOneColor = Colors.red;
//                        });
//                      },
//                      child: Container(
//                        color: pageOneColor,
//                        child: Center(
//                          child: Text('Container A'),
//                        ),
//                      ),
//                    ),
                  ),
                ),
                Container(
                  /// remove Container B will see the correct color changing of Container A
                  color: Colors.grey,
                  child: Center(
                    child: Text('Container B'),
                  ),
                ),
              ],
              onPageChanged: (int pageId) {
                setState(() {
                  debugPrint('pageId:$pageId');
                  _tabController.index = pageId;
                });
              },
            ),
          ),
        ],
      ),
    );
  }

  _onTapDown(TapDownDetails details) {
    print(details);
    setState(() {
      isTapped = true;
      pageOneColor = Colors.yellow;
    });
  }

  _onTapUp(TapUpDetails details) {
    print(details);
    setState(() {
      isTapped = false;
      pageOneColor = Colors.red;
    });
  }

  _onTapCancel() {
    print('tap cancelled');
    setState(() {
      isTapped = false;
      pageOneColor = Colors.red;
    });
  }
}

class CustomButtonGestureRecognizer extends OneSequenceGestureRecognizer {
  final Function onTapDown;
  final Function onTapUp;
  final Function onTapCancel;

  CustomButtonGestureRecognizer(
      {@required this.onTapDown,
      @required this.onTapUp,
      @required this.onTapCancel});

  @override
  void addPointer(PointerEvent event) {
    if (event is PointerDownEvent) {
      onTapDown(TapDownDetails());
      startTrackingPointer(event.pointer);
      resolve(GestureDisposition.accepted);
    } else {
      stopTrackingPointer(event.pointer);
    }
  }

  @override
  void handleEvent(PointerEvent event) {
    if (event is PointerDownEvent) {
      print('tap down detected');
      onTapDown(TapDownDetails());
    }
    if (event is PointerUpEvent) {
      print('tap up detected');
      onTapUp(TapUpDetails());
      stopTrackingPointer(event.pointer);
    }
    if (event is PointerCancelEvent) {
      print('tap cancel detected');
      onTapCancel();
      stopTrackingPointer(event.pointer);
    }
  }

  @override
  String get debugDescription => 'customButtonTap';

  @override
  void didStopTrackingLastPointer(int pointer) {}
}

4

0 回答 0