gpt4 book ai didi

flutter - 如何在 PageView 内的 TabBarView 上滚动 "merge"?

转载 作者:行者123 更新时间:2023-12-03 03:08:42 27 4
gpt4 key购买 nike

我有一个在其主页上使用 PageView 的应用程序。今天,我被指派在其中一个页面中插入一个 TabBarView。问题是当我在最后一个选项卡中滚动选项卡之间时,向左滚动不会滚动 PageView。

我需要一种方法使页面 View 的滚动在 tabbarview 的开始或结束时滚动。

我发现了一个倒排题:flutter PageView inside TabBarView: scrolling to next tab at the end of page

但是,那里说的方法不适合我的问题。

我做了一个最小的例子:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
title: 'TabBarView inside PageView',
home: MyHomePage(),
);
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final PageController _pageController = PageController();

@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('TabBarView inside PageView'),
),
body: PageView(
controller: _pageController,
children: <Widget>[
Container(color: Colors.red),
GreenShades(),
Container(color: Colors.yellow),
],
),
);
}

class GreenShades extends StatefulWidget {
@override
_GreenShadesState createState() => _GreenShadesState();
}

class _GreenShadesState extends State<GreenShades>
with SingleTickerProviderStateMixin {
TabController _tabController;

@override
void initState() {
this._tabController = TabController(length: 3, vsync: this);
super.initState();
}

@override
Widget build(BuildContext context) => Column(
children: <Widget>[
TabBar(
labelColor: Colors.green,
indicatorColor: Colors.green,
controller: _tabController,
tabs: <Tab>[
const Tab(text: "Dark"),
const Tab(text: "Normal"),
const Tab(text: "Light"),
],
),
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
Container(color: Colors.green[800]),
Container(color: Colors.green),
Container(color: Colors.green[200]),
],
),
)
],
);

@override
void dispose() {
_tabController.dispose();
super.dispose();
}
}

请注意,在此 MRE 中,如果拖动 TabBar 可以到达第 3 页,但如果拖动 TabBarView 则不能。

我怎样才能实现这种行为?


编辑:

正如@Fethi 所说,有一个类似的问题: Is it possible to swipe from an TabBarView content area to an adjacent PageView page?

然而,这个问题没有得到令人满意的回答,因为给出的解决方案并没有真正“混合”卷轴,尽管行为与所描述的类似。它不会自然滚动。

最佳答案

这可以通过使用 PageController.postion 属性的 drag 方法实现,该方法在内部拖动屏幕的 ScrollPosition。这样,用户可以直观地拖动页面,例如拖到一半然后离开或完全继续。

这个想法的灵感来自另一篇使用 OverScrollNotification 的帖子,但添加了更多步骤以继续直观拖动。

  1. 在用户开始滚动时收集 DragstartDetail。
  2. 监听 OverScrollNotification 并开始拖动,同时使用 drag.update 和来自 OverscrollNotification 方法的 DragUpdateDetails 更新拖动。
  3. 在 ScrollEndNotification 上取消拖动。

为了使想法简单,我只粘贴选项卡页面的构建方法。

dart pad 中提供了一个完整的示例.

demo

  @override
Widget build(BuildContext context) {
// Local dragStartDetail.
DragStartDetails dragStartDetails;
// Current drag instance - should be instantiated on overscroll and updated alongside.
Drag drag;
return Column(
children: <Widget>[
TabBar(
labelColor: Colors.green,
indicatorColor: Colors.green,
controller: _tabController,
tabs: <Tab>[
const Tab(text: "Dark"),
const Tab(text: "Normal"),
const Tab(text: "Light"),
],
),
Expanded(
child: NotificationListener(
onNotification: (notification) {
if (notification is ScrollStartNotification) {
dragStartDetails = notification.dragDetails;
}
if (notification is OverscrollNotification) {
drag = _pageController.position.drag(dragStartDetails, () {});
drag.update(notification.dragDetails);
}
if (notification is ScrollEndNotification) {
drag?.cancel();
}
return true;
},
child: TabBarView(
controller: _tabController,
children: <Widget>[
Container(color: Colors.green[800]),
Container(color: Colors.green),
Container(color: Colors.green[200]),
],
),
),
),
],
);
}

Old Answer

以上可能无法处理某些边缘情况。如果您需要更多控制,下面的代码会提供相同的结果,但您可以处理 UserScrollNotification。我粘贴这个是因为,它可能对其他想知道使用 ScrollView 的 Axis 滚动方向的人有用。

              if (notification is ScrollStartNotification) {
dragStartDetails = notification.dragDetails;
}

if (notification is UserScrollNotification &&
notification.direction == ScrollDirection.forward &&
!_tabController.indexIsChanging &&
dragStartDetails != null &&
_tabController.index == 0) {
_pageController.position.drag(dragStartDetails, () {});
}

// Simialrly Handle the last tab.
if (notification is UserScrollNotification &&
notification.direction == ScrollDirection.reverse &&
!_tabController.indexIsChanging &&
dragStartDetails != null &&
_tabController.index == _tabController.length - 1) {
_pageController.position.drag(dragStartDetails, () {});
}

关于flutter - 如何在 PageView 内的 TabBarView 上滚动 "merge"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60642631/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com