'Column child PageView interaction through the whole screen
I'm trying to create a screen as follows:
The bottom part is PageView.builder. I want it to be interactable through the whole screen.
The first thing I came up with was wrapping them in a stack, creating an invisible PageView on the top, and synchronizing the bottom and invisible(top) PageViews' controllers. But, in this case, the button doesn't receive input.
PS: Wrapping the top PageView by a listener with HitTestBehavior.translucent didn't work. I think PageView doesn't let tap events propagate.
How can I aproach this screen?
class Test extends StatelessWidget {
Test({Key? key}) : super(key: key);
final pageController = PageController();
final infoPages = [
Container(
color: Colors.blue[200],
child: Text("info 1"),
),
Container(
color: Colors.blue[400],
child: Text("info 2"),
),
Container(
color: Colors.blue[600],
child: Text("info 3"),
),
];
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.grey,
child: Text("this is a static image"),
)),
Expanded(
child: TextButton(
onPressed: () {
print("button pressed");
},
child: const Text("This is a static button"),
),
),
Expanded(
flex: 2,
child: PageView.builder(
controller: pageController,
itemCount: infoPages.length,
itemBuilder: ((context, index) {
return infoPages[index];
}),
),
),
],
);
}
}
Solution 1:[1]
Dear parallel universe me; I solved it by wrapping it with a stack, disabling the PageView interaction, and controlling it with a GestureDetector.
class Test extends StatefulWidget {
Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
final pageController = PageController();
final infoPages = [
Container(
color: Colors.blue[200],
child: Text("info 1"),
),
Container(
color: Colors.blue[400],
child: Text("info 2"),
),
Container(
color: Colors.blue[600],
child: Text("info 3"),
),
];
late double offset;
late double start;
bool snap = true;
@override
Widget build(BuildContext context) {
return Stack(children: [
Column(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.grey,
child: Text("this is a static image"),
),
),
Expanded(
child: TextButton(
onPressed: () {
print("button pressed");
},
child: const Text("This is a static button"),
),
),
Expanded(
flex: 2,
child: PageView.builder(
pageSnapping: snap,
physics: const NeverScrollableScrollPhysics(),
controller: pageController,
itemCount: infoPages.length,
itemBuilder: ((context, index) {
return infoPages[index];
}),
),
),
],
),
GestureDetector(
onHorizontalDragStart: (details) {
offset = pageController.offset;
start = details.globalPosition.dx;
setState(() {
snap = false;
});
},
onHorizontalDragUpdate: (details) {
final dx = details.globalPosition.dx - start;
double temp = offset - dx;
pageController.jumpTo(temp);
},
onHorizontalDragEnd: (details) {
setState(() {
snap = true;
});
},
)
]);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | srkn |