Adr*_*rek 5 dart flutter flutter-layout flutter-pageview
如何更新PageView为仅在特定条件下触发onPageChange?
在这里,如果用户仍在触摸屏幕,我不想更改当前页面。除此之外,一切都应该保持不变(弹道滚动模拟、页面限制)
看来它必须处理ScrollPhysics附加到 的对象PageView,但我不知道如何正确扩展它。
如果您需要一些代码,请告诉我,但问题非常笼统,可以引用任何PageView,因此您不需要任何上下文。
这是上面文本的dart翻译。请随意更新此代码以使其实现目标。
// main.dart
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return const MaterialApp(title: _title, home: MyPageView());
}
}
class MyPageView extends StatefulWidget {
const MyPageView({Key? key}) : super(key: key);
@override
State<MyPageView> createState() => _MyPageViewState();
}
class _MyPageViewState extends State<MyPageView> {
@override
Widget build(BuildContext context) {
final PageController controller = PageController();
return Scaffold(
body: SafeArea(
child: PageView.builder(
onPageChanged: (int index) {
// TODO: Don't trigger this function if you still touch the screen
print('onPageChanged index $index, ${controller.page}');
},
allowImplicitScrolling: false,
controller: controller,
itemBuilder: (BuildContext context, int index) {
print('Build Sliver');
return Center(
child: Text('Page $index'),
);
},
)));
}
}
Run Code Online (Sandbox Code Playgroud)
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return const MaterialApp(title: _title, home: MyPageView());
}
}
class MyPageView extends StatefulWidget {
const MyPageView({Key? key}) : super(key: key);
@override
State<MyPageView> createState() => _MyPageViewState();
}
class _MyPageViewState extends State<MyPageView> {
@override
Widget build(BuildContext context) {
final PageController controller = PageController();
return Scaffold(
body: SafeArea(
child: Listener(
onPointerUp: (PointerUpEvent event) {
if (controller.page == null) {
return;
}
if (controller.page! > 0.5) {
//TODO: update the time so it fits the end of the animation
Future.delayed(const Duration(milliseconds: 700), () {
print('Do your custom action onPageChange action here');
});
}
},
child: PageView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
print('Build Sliver');
return Center(
child: Text('Page $index'),
);
},
),
),
));
}
}
Run Code Online (Sandbox Code Playgroud)
该解决方案在用户停止触摸屏幕700 毫秒后触发下一页的操作。
它确实有效,但这是一项糟糕的工作。
controller.page(越接近下一页,您需要等待的时间越小)而变化。onHorizontalDragEnd或类似的拖动检测器,这可能会导致不需要的行为。您应该使用 完全禁用滚动PageView,并physics: NeverScrollableScrollPhysics()使用 自行检测左右滚动GestureDetector。通过检查参数的属性,将GestureDetector.onHorizontalDragEnd告诉用户拖动的方向是向左还是向右。如果该值为负,则用户向右拖动;如果用户向左拖动,则该值为正。DragEndDetailsprimaryVelocity
要手动更改页面,只需使用PageController方法nextPage和previousPage。
看看下面的屏幕截图和DartPad 上的现场演示。
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
debugShowCheckedModeBanner: false,
scrollBehavior: MyCustomScrollBehavior(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late PageController _pageController;
@override
void initState() {
super.initState();
_pageController = PageController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onHorizontalDragEnd: (details) => (details.primaryVelocity ?? 0) < 0
? _pageController.nextPage(
duration: const Duration(seconds: 1), curve: Curves.easeInOut)
: _pageController.previousPage(
duration: const Duration(seconds: 1), curve: Curves.easeInOut),
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: [
Container(
color: const Color.fromARGB(255, 0, 91, 187),
),
Container(
color: const Color.fromARGB(255, 255, 213, 0),
),
],
),
),
);
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2165 次 |
| 最近记录: |