我实施了一个类似于this的perspective_page_view
.我更新了代码到新的Flutter 版本,一切工作正常.
问题是,我希望这PageView
分能有infinite loop分.
我try 了this个问题的多种不同解决方案,但都没有奏效.他们都把我的观点搞砸了.
我觉得这应该是可能的,但我想不出解决办法.感谢您的每一次帮助!如果你需要更多的信息,请告诉我!
Minimal Producable Example:个
我的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,
);
},
),
),
),
),
);
}
}
而前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',
),
),
),
]
],
),
);
}