[英]In flutter How to make the inner widget with pan gesture will not conflict with PageView
[英]In Flutter how to make PageView scroll faster? The animation seems to be slow and the inner ListView cant response my vertical gesture
你可以在视频中看到细节
不知道怎么解决这个问题。。对比Android Native ViewPager,Flutter中PageView的动画好像比较慢,用户只能等这个慢动画完全停止,才能拖动内部ListView。感觉用户体验比原生android ViewPager差。希望有一个完美的解决方案。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/reactive_page_view/reactive_page_view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Page(),
);
}
}
class Page extends StatefulWidget {
@override
_PageState createState() => _PageState();
}
PageView view;
class _PageState extends State<Page> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CupertinoNavigationBar(
middle: Text("Demo"),
),
body: PageView.builder(
physics: BouncingScrollPhysics(),
itemCount: 3,
itemBuilder: (context, index) {
return ItemPage();
}),
);
}
}
class ItemPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: 30,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text('这是第$index', style: TextStyle(fontSize: 30)),
);
});
}
}
您可以定义自己的 PageController 实例并使用其方法 nextPage() 和 previousPage()。 他们有“持续时间”参数来控制页面视图滚动的速度。
final PageController controller = PageController(
viewportFraction: 0.9,
);
void nextPage() async {
await controller.nextPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
void prevPage() async {
await controller.previousPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
然后将此控制器应用于您的页面视图:
return PageView.builder(
physics: NeverScrollableScrollPhysics(),
controller: controller,
...
);
main.dart 的完整代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyPageViewExample(),
);
}
}
class MyPageViewExample extends StatelessWidget {
MyPageViewExample({Key key}) : super(key: key);
final PageController controller = PageController(
viewportFraction: 0.9,
);
void nextPage() async {
await controller.nextPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
void prevPage() async {
await controller.previousPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeOut,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
color: Colors.grey[100],
),
Padding(
padding: EdgeInsets.only(top: 20.0 + MediaQuery.of(context).padding.top, bottom: 20.0),
child: _buildCarousel(context),
),
],
),
);
}
Widget _buildCarousel(BuildContext context) {
return PageView.builder(
physics: NeverScrollableScrollPhysics(),
controller: controller,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int itemIndex) {
return _buildItem(context, itemIndex);
},
itemCount: 5,
);
}
Widget _buildItem(BuildContext context, int itemIndex) {
return Padding(
padding: EdgeInsets.only(left: 4.0, top: 10.0, right: 4.0, bottom: 10.0),
child: GestureDetector(
onPanUpdate: (details) {
if (details.delta.dx < 0) {
nextPage();
}
if (details.delta.dx > 0) {
prevPage();
}
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(35.0)),
),
child: Center(
child: Text(
'Item ' + (itemIndex + 1).toString(),
),
),
),
),
);
}
}
您可以控制滚动动画的一般物理。
PageView(
physics: CustomPageViewScrollPhysics(),
控制滚动行为:
class CustomPageViewScrollPhysics extends ScrollPhysics {
const CustomPageViewScrollPhysics({ScrollPhysics? parent})
: super(parent: parent);
@override
CustomPageViewScrollPhysics applyTo(ScrollPhysics? ancestor) {
return CustomPageViewScrollPhysics(parent: buildParent(ancestor)!);
}
@override
SpringDescription get spring => const SpringDescription(
mass: 50,
stiffness: 100,
damping: 0.8,
);
}
您还应该能够计算质量、刚度、阻尼的持续时间,但我相信这些选项更适合您的问题。 来源
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.