【发布时间】:2018-12-24 09:29:43
【问题描述】:
我想在 Flutter 中嵌套 PageView,在 PageView 中的 Scaffold 中使用 PageView。在外部 PageView 中,我将有徽标和联系信息,以及辅助信息。作为一个孩子,我将有一个带有内部 PageView 和一个 BottomNavigationBar 作为主要用户交互屏幕的脚手架。这是我到目前为止的代码:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp>{
int index = 0;
final PageController pageController = PageController();
final Curve _curve = Curves.ease;
final Duration _duration = Duration(milliseconds: 300);
_navigateToPage(value){
pageController.animateToPage(
value,
duration: _duration,
curve: _curve
);
setState((){
index = value;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PageViewCeption',
home: PageView(
children: <Widget>[
Container(
color: Colors.blue,
),
Scaffold(
body: PageView(
controller: pageController,
onPageChanged: (page){
setState(() {
index = page;
});
},
children: <Widget>[
Container(
child: Center(
child: Text('1', style: TextStyle(color: Colors.white))
)
),
Container(
child: Center(
child: Text('2', style: TextStyle(color: Colors.white))
)
),
Container(
child: Center(
child: Text('3', style: TextStyle(color: Colors.white))
)
),
],
),
backgroundColor: Colors.green,
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: (value) =>_navigateToPage(value),
currentIndex: index,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.cake),
title: Text('1')
),
BottomNavigationBarItem(
icon: Icon(Icons.cake),
title: Text('2')
),
BottomNavigationBarItem(
icon: Icon(Icons.cake),
title: Text('3')
)
],
),
),
Container(
color: Colors.blue
)
],
),
);
}
}
结果如下:
问题是:当我在内部PageView中时,我无法从它离开到外部页面在第一页上向左滚动,或者在内部PageView的最后一页上向右滚动。在 BottomNavigationBar 上滚动(滑动)返回外部 PageView 的唯一方法。 在 Scroll Physics Class 的 the docs 中,我们在描述中找到了这个:
例如,确定当用户达到最大滚动范围或用户停止滚动时 Scrollable 的行为方式。
但我还没有想出解决方案。有什么想法吗?
更新 1
我在使用 CustomScrollPhysics 类方面取得了进展:
class CustomScrollPhysics extends ScrollPhysics{
final PageController _controller;
const CustomScrollPhysics(this._controller, {ScrollPhysics parent }) : super(parent: parent);
@override
CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
return CustomScrollPhysics(_controller, parent: buildParent(ancestor));
}
@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
assert(() {
if (value == position.pixels) {
throw new FlutterError(
'$runtimeType.applyBoundaryConditions() was called redundantly.\n'
'The proposed new position, $value, is exactly equal to the current position of the '
'given ${position.runtimeType}, ${position.pixels}.\n'
'The applyBoundaryConditions method should only be called when the value is '
'going to actually change the pixels, otherwise it is redundant.\n'
'The physics object in question was:\n'
' $this\n'
'The position object in question was:\n'
' $position\n'
);
}
return true;
}());
if (value < position.pixels && position.pixels <= position.minScrollExtent){ // underscroll
_controller.jumpTo(position.viewportDimension + value);
return 0.0;
}
if (position.maxScrollExtent <= position.pixels && position.pixels < value) {// overscroll
_controller.jumpTo(position.viewportDimension + (value - position.viewportDimension*2));
return 0.0;
}
if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) // hit top edge
return value - position.minScrollExtent;
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) // hit bottom edge
return value - position.maxScrollExtent;
return 0.0;
}
}
这是对 ClampingScrollPhysics applyBoundaryConditions 的修改。它有点工作,但由于 pageSnapping 它真的是错误的。它发生了,因为根据the docs:
任何活动的动画都会被取消。如果用户当前正在滚动,那 操作被取消。
当操作被取消时,如果用户停止拖动屏幕,PageView 开始快速返回到 Scafold 页面,这会使事情变得混乱。关于在这种情况下如何避免页面捕捉或更好地实施的任何想法?
【问题讨论】:
-
我不知道如何用一个大的 PageView 实现相同的结果。有什么想法吗?
-
已经有一段时间了,但我认为嵌套是可能的。只听滚动的拖动事件。 (如果您在最后一个选项卡幻灯片(选项卡的长度)上使用 * 物理禁用内部滚动:leftDragActive ? NeverScrollableScrollPhysics() : PageScrollPhysics() * 让我知道它是否有效 :)