Reputation: 180
I have a smaller element on a screen that I'm using a PageView to build, since I need that snap-to effect for each item in the list. But this means the edges will be flush, with no visual indication that the PageView element is scrollable. I tried putting the PageView in a stack with a container on top (like an overlay) that had a linear gradient to "shadow" the sides to make the element look rounded, but this blocks the scrolling gesture from reaching the PageView.
My question is this: is there a widget that I'm not finding that allows scroll gestures to pass through it, while visually appearing on top of other elements? I know I can draw smaller-than-the-PageView elements on top of it, but I'm just wondering if someone else has done something like this successfully.
EDIT: here is a simplified version of the working code. I can't swipe to the next page view.
return Scaffold(
body: Center(
child: Container(
padding: const EdgeInsets.all(35.0),
child: Stack(
children: [
PageView(
children: [
Container(color: Colors.blue[200]),
Container(color: Colors.red[200]),
Container(color: Colors.deepPurple[200])
]
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [ Color.fromARGB(50, 0, 0, 0), Color.fromARGB(0, 0, 0, 0), Color.fromARGB(0, 0, 0, 0), Color.fromARGB(50, 0, 0, 0) ],
stops: [ 0.05, 0.25, 0.75, 0.95 ]
)
)
)
]
)
),
),
);
Upvotes: 0
Views: 1751
Reputation: 180
It seems Containers block scroll input, so I decided to go another route with something like Pedro R.'s suggestion. I created a page indicator at the bottom of the PageView that indicates which page the user is currently on and how many pages total there are. Here is the CodePen I made to showcase the effect.
EDIT AND BEST ANSWER: So I found exactly what I was looking for a little while later. It's a class called IgnorePointer
, and it works like the below code example. This will allow you to swipe on the PageView
. Try removing the IgnorePointer
and your swiping becomes blocked.
Stack(
children: <Widget>[
PageView(
children: <Widget>[
Container(color: Colors.deepPurple[300]),
Container(color: Colors.blue[300]
]
),
IgnorePointer(
child: Container(
color: Color.fromARGB(100, 100, 100, 100)
)
)
]
)
And the code to go with the code pen
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyWidget(),
),
);
}
class MyWidget extends StatelessWidget {
MyWidget({Key key}): super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
padding: const EdgeInsets.all(35.0),
child: PageIndicator()
),
),
);
}
}
class PageIndicator extends StatefulWidget {
PageIndicator({Key key}): super(key: key);
@override
_PageIndicatorState createState() => _PageIndicatorState();
}
class _PageIndicatorState extends State<PageIndicator> {
int _pageNum;
PageController _controller;
@override
void initState() {
super.initState();
_pageNum = 0;
_controller = PageController(initialPage: 0);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
PageView(
controller: _controller,
onPageChanged: (page) {
setState(() {
_pageNum = page;
});
},
children: [
Container(color: Colors.blue[200]),
Container(color: Colors.red[200]),
Container(color: Colors.deepPurple[200])
]
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: 200,
height: 80,
child: Center(
child: Text("${_pageNum + 1} / 3", style: TextStyle(fontSize: 25.0))
)
)
)
]
);
}// end build
}
Upvotes: 4
Reputation: 673
You could use a PageIndicatorWidget. Something like this: var pageController = PageController();
Stack(
children: [
PageView(
controller: pageController,
children: [
Container(color: Colors.blue[200]),
Container(color: Colors.red[200]),
Container(color: Colors.deepPurple[200])
]
),
PageIndicator(
layout: PageIndicatorLayout.WARM,
size: 10.0,
controller: pageController,
space: 5.0,
count: 3,
color: Colors.green,
activeColor: Colors.gray,
),
]
)
Upvotes: 0