我有2个具有不同viewportFraction的PageViews。有什么方法可以滚动其中一个PageView,而另一个可以滚动在同一页面或偏移量上吗?
还问,是否可以将PageView控制在代码中的偏移量的中间?
class MyPageControllers extends StatefulWidget {
@override
_MyPageControllersState createState() => _MyPageControllersState();
}
class _MyPageControllersState extends State<MyPageControllers> {
PageController _controller1;
PageController _controller2;
Widget _itemBuilder(BuildContext context, int index) => Container(
color: Colors.primaries[index % Colors.primaries.length],
child: Center(
child: Text(
index.toString(),
style: TextStyle(color: Colors.white, fontSize: 60),
),
),
);
@override
void initState() {
super.initState();
_controller1 = PageController(viewportFraction: 0.8);
_controller2 = PageController(viewportFraction: 0.5);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: PageView.builder(
controller: _controller1,
itemBuilder: _itemBuilder,
),
),
SizedBox(
height: 40,
),
Expanded(
child: PageView.builder(
controller: _controller2,
itemBuilder: _itemBuilder,
),
),
],
);
}
}
答案 0 :(得分:1)
因此,您需要在call ..\venv\Scripts\activate.bat
pytest -v src/datasets_test.py::TestDatasetsOperations::test_dataset_add
小部件之一的PageView
(PageController
)上附加一个侦听器,然后更改另一个{{1} }小部件的_controller1
(offset
)。
初始化控制器后,您需要在PageView
中添加这段代码:
PageController
更新后的答案(已选择页面同步):
_controller2
更新后的答案(具有手动滚动检测功能):
initState
答案 1 :(得分:0)
我发现受@yusufpats解决方案启发的黑客解决方案。我在下面描述了更多细节:
这部分有点棘手,因为当控制器彼此听时,页面实际上会卡住并且无法滚动(为什么?)。我添加bool来检查正在滚动的滚动条并需要收听。
bool _isPage1Scrolling;
bool _isPage2Scrolling;
void initState() {
_isPage1Scrolling = false;
_isPage2Scrolling = false;
...
_controller1.addListener(() {
if(_isPage1Scrolling){
// Control _controller2
}
}
_controller2.addListener(() {
if(_isPage1Scrolling){
// Control _controller2
}
}
这是最难的部分,因为如果我使用animateTo
或jumpTo
,则“受控控制器”看起来很奇怪并且看起来不太流畅。这是设计使然,当用户调用这两个函数时,页面在很短的时间到达该位置(反弹回到稳定的页面位置)后,始终会转到“ BallisticScrollActivity”。我从控制器内的ScrollPosition
中找到了一些解决方案,但似乎只有最后一个可以做得很好,而且没有警告:
我将offset
用作第一页的班次,并按viewportFraction
计算另一页的班次
// Control _controller2
// _controller2.position.jumpToWithoutSettling(...
// _controller2.position.forcePixels(...
_controller2.position.correctPixels(_controller1.offset * _controller2.viewportFraction / _controller1.viewportFraction);
_controller2.position.notifyListeners();
我使用NotificationListener
而不使用GestureDetector
,因为onTapDown
和onTapUp
不适合滚动通知。有时,我快速触摸并滚动时没有onTapDown
事件。
我研究了通知类型并在里面找到了一些东西
可能有更好的方法来检测它。我只是想出一种简单的方法。
...
child: NotificationListener(
onNotification: (notification){
if(notification is UserScrollNotification){
if(notification.direction != ScrollDirection.idle){
(_controller2.position as ScrollPositionWithSingleContext).goIdle();
_isPage1Scrolling = true;
_isPage2Scrolling = false;
}
else{
_isPage1Scrolling = false;
}
}
return false;
},
child: PageView.builder(
...
也许有人注意到以下行:
(_ controller2.position as ScrollPositionWithSingleContext).goIdle();
此行用于If I drag the firs PageView and then drag anther PageView before the first one return to a stable position
的边缘保护套。第一个PageView的滚动位置仍处于BallisticScrollActivity状态,我需要强制使其空闲才能控制它。
欢迎任何建议!