I implemented a perspective_page_view
like this. I updated the code to the new Flutter Version and everything is working fine.
The thing is that I would like that PageView
to have an infinite loop.
I tried multiple different solutions I found on this question but non of them worked. They all messed up the perspective in my case.
I feel like this should be possible, but I can not come up with a solution. Happy for every help! Let me know if you need any more info!
Minimal Producable Example:
My Scaffold
:
class ProjectsViewState extends State<ProjectsView>
with TickerProviderStateMixin {
late PageViewHolder holder;
late PageController _controller;
double fraction = 0.50;
@override
void initState() {
super.initState();
holder = PageViewHolder(value: 2.0);
_controller = PageController(initialPage: 2, viewportFraction: fraction);
_controller.addListener(() {
holder.setValue(_controller.page);
});
}
int currentPage = 2;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ChangeNotifierProvider<PageViewHolder>.value(
value: holder,
child: Flexible(
child: PageView.builder(
controller: _controller,
onPageChanged: (value) {
setState(() {
currentPage = value;
});
},
itemCount: projectsCounter,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return ProjectsGalleryView(
number: index.toDouble(),
fraction: fraction,
);
},
),
),
),
),
);
}
}
and the pageView
:
class ProjectsGalleryView extends StatefulWidget {
final double number;
final double fraction;
const ProjectsGalleryView(
{super.key, required this.number, required this.fraction});
@override
State<ProjectsGalleryView> createState() => _ProjectsGalleryViewState();
}
class _ProjectsGalleryViewState extends State<ProjectsGalleryView>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
double value = Provider.of<PageViewHolder>(context).value;
double diff = (widget.number - value);
//Matrix for Elements
final Matrix4 pvMatrix = Matrix4.identity()
..setEntry(3, 3, 1 / 0.8) // Increasing Scale by 80%
// ..setEntry(1, 1, widget.fraction) // Changing Scale Along Y Axis
..setEntry(3, 0, 0.003 * -diff); // Changing Perspective Along X Axis
return Transform(
transform: pvMatrix,
alignment: FractionalOffset.center,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: SizedBox(
height: 200,
width: 200,
child: Container(
decoration: BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.circular(10),
),
),
),
),
if (diff <= 1.0 && diff >= -1.0) ...[
AnimatedOpacity(
duration: const Duration(milliseconds: 100),
opacity: 1 - diff.abs(),
child: const Padding(
padding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 20,
),
child: Text(
'A Text with animated opacity',
),
),
),
]
],
),
);
}
2
Answers
Isn’t the accepted answer in the related question you linked also working?
simply not providing the
itemCount: projectsCounter
resulted in the following:is this what you’re after?
code
Edit:
sorry, dont have enough karma to comment but:
yes i can scroll infinitely (more then 3 times lol), i have rebuilt a new flutter app with newer versions and v2 embeddings, i can create and link you the repo if you want
Well if you want the scroll to be smooth on the left side as well. You just have to set arbitrarily
LARGE NUMBER
as a starting point so that it feelsINFINITE
(large number like 9 trillion). However, it won’t scroll indefinitely.const largeInt = 9223372036854;
)initState
like belowAnd the Full Code for the
ProjectView
// Previous answer
TL;DR It’s not a perfect solution, but to scroll infinitely on the left side as well, add
jumpToPage
inside the_controller.addListener
First, do not include
itemCount
inPageview.builder
or set it tonull
.However, Even though you set
itemCount
tonull
, it still ends when theindex
is0
.So, in the
initState
add following after initializingPageController
.by adding
_controller.jumpToPage(10)
when_controller.page
is in betweem 1.99 and 2.01,_pageController
will set the page to 10 again.The reason I added this in the
_controller.addListener
is that if you put that inonPageChanged
, it will stutter real bad since the returnedvalue
isint
.However, even though I used the double to minimize the impact, it will still kinda stutter a bit when scrolling really fast, and if its extremely fast, there is a chance that it will not work. However, this will always work for normal page by page scrolling.
The full code for your
ProjectView Widget
.