Chr*_*ris 5 dart flutter flutter-pageview
我实现了这样perspective_page_view的。我将代码更新到新的 Flutter 版本,一切正常。
问题是我希望它PageView有一个无限循环。
我尝试了在这个问题上找到的多种不同的解决方案,但没有一个有效。他们都搞乱了我的观点。
我觉得这应该是可能的,但我无法想出解决方案。为每一次帮助感到高兴!如果您需要更多信息,请告诉我!
最小可生产示例:
我的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,
);
},
),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
和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',
),
),
),
]
],
),
);
}
Run Code Online (Sandbox Code Playgroud)
好吧,如果您希望左侧的滚动也平滑。你只需要任意设定LARGE NUMBER一个起点,这样就可以感觉到INFINITE(像9万亿这样的大数字)。但是,它不会无限期地滚动。
const largeInt = 9223372036854;:)initState喜欢如下@override
void initState() {
super.initState();
holder = PageViewHolder(value: largeInt.toDouble());
_controller = PageController(
initialPage: largeInt,
viewportFraction: fraction,
);
_controller.addListener(() {
holder.setValue(_controller.page);
});
}
Run Code Online (Sandbox Code Playgroud)
以及完整的代码ProjectView
const largeInt = 9223372036854;
class ProjectsView extends StatefulWidget {
const ProjectsView({super.key});
@override
ProjectsViewState createState() => ProjectsViewState();
}
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: largeInt.toDouble());
_controller = PageController(
initialPage: largeInt,
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: Column(
children: [
Flexible(
child: PageView.builder(
controller: _controller,
onPageChanged: (value) {
setState(() => _currentPage = value);
},
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return ProjectsGalleryView(
number: index.toDouble(),
fraction: fraction,
);
},
),
),
],
)),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
// 之前的答案
TL;DR 这不是一个完美的解决方案,但要在左侧无限滚动,请jumpToPage在_controller.addListener
首先,不要包含itemCount在Pageview.builder或将其设置为null.
然而,即使你设置itemCount为,它仍然会在isnull时结束。index0
因此,在initState初始化后添加以下内容PageController。
_controller.addListener(() {
holder.setValue(_controller.page);
final page = _controller.page;
if (page == null) return;
if (page < 2.01 && page > 1.99) {
_controller.jumpToPage(10);
}
});
Run Code Online (Sandbox Code Playgroud)
通过在 1.99 和 2.01 之间添加_controller.jumpToPage(10)when ,将再次将页面设置为 10。_controller.page_pageController
我在 中添加这个的原因_controller.addListener是,如果你把它放进去onPageChanged,它会非常糟糕,因为返回的value是int.
然而,尽管我使用了双倍来最小化影响,但当滚动得非常快时,它仍然会有点卡顿,如果它非常快,它有可能无法工作。但是,这对于正常的逐页滚动始终有效。
您的ProjectView Widget.
class ProjectsView extends StatefulWidget {
const ProjectsView({super.key});
@override
ProjectsViewState createState() => ProjectsViewState();
}
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);
final page = _controller.page;
if (page == null) return;
if (page < 2.01 && page > 1.99) {
_controller.jumpToPage(10);
}
});
}
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);
},
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return ProjectsGalleryView(
number: index.toDouble(),
fraction: fraction,
);
},
),
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
618 次 |
| 最近记录: |