我有一个包裹在 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) {}
}