管理 SingleChildScrollView 内 SingleChildScrollView 的滚动 - 抖动?

Manage scrolling for SingleChildScrollView inside a SingleChildScrollView - flutter?

我有一个父 SCS 视图 (SingleChildScrollView) 和一个子 SCS 视图。在子 SCS 视图中有一个数据 Table,数据 Table 从屏幕底部四分之一左右开始。

现在,当用户滚动到子 SCS 视图中数据 Table 的顶部时,我想滚动父 SCS 视图。

这在 web 中自然有效,但在 iOS 或 anroid 中无效。我尝试对父 SCS 视图和子 SCS 视图使用相同的 Scrollcontroller,并尝试使用 ScrollPhysics。但似乎没有任何效果。你能帮我解决一下吗?

代码如下:

    import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Report'),
        ),
      ),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: [
          Text('Some Data', style: TextStyle(fontSize: 30)),
          Text('Some Data', style: TextStyle(fontSize: 30)),
          Text('Some Data', style: TextStyle(fontSize: 30)),
          Text('Some Data', style: TextStyle(fontSize: 30)),
          Text('Some Data', style: TextStyle(fontSize: 30)),
          Text('Some Data', style: TextStyle(fontSize: 30)),
          ConstrainedBox(
            constraints: BoxConstraints(
              maxHeight: 400,
            ),
            child: Scrollbar(
              controller: scrollController,
              child: SingleChildScrollView(
                controller: scrollController,
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: DataTable(
                    columns: [
                      DataColumn(label: Text('Sl. No.')),
                      DataColumn(label: Text('Resource Name')),
                      DataColumn(label: Text('Score at 1')),
                      DataColumn(label: Text('Score at 2')),
                      DataColumn(label: Text('Final Score')),
                    ],
                    rows: [
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

谢谢。

已编辑

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:so_test/screen/video_player.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  UniqueKey _key = UniqueKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Test(),
    );
  }
}

class Test extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TestState();
  }
}

class _TestState extends State<Test> {
  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          shrinkWrap: true,
          physics: ScrollPhysics(),
          children: [
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Text('Some Data', style: TextStyle(fontSize: 30)),
            Scrollbar(
              controller: scrollController,
              child: SingleChildScrollView(
                controller: scrollController,
                physics: NeverScrollableScrollPhysics(),
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: DataTable(
                    columns: [
                      DataColumn(label: Text('Sl. No.')),
                      DataColumn(label: Text('Resource Name')),
                      DataColumn(label: Text('Score at 1')),
                      DataColumn(label: Text('Score at 2')),
                      DataColumn(label: Text('Final Score')),
                    ],
                    rows: [
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                      DataRow(
                        cells: [
                          DataCell(Text('1')),
                          DataCell(Text('Person 1')),
                          DataCell(Text('5')),
                          DataCell(Text('2')),
                          DataCell(Text('8')),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

可以使用NotificationListener监听OverscrollNotification检测嵌套列表的上边界命中,通过控制滚动到外层Scrollview

我将您的问题简化为以下示例代码:

class MyNestedListView extends StatefulWidget {
  const MyNestedListView({Key? key}) : super(key: key);

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

class _MyNestedListViewState extends State<MyNestedListView> {
  final _controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    return ListView(
      controller: _controller,
      children: [
        Placeholder(fallbackHeight: 400),
        Placeholder(fallbackHeight: 400),
        Placeholder(fallbackHeight: 400),
        Container(
          padding: EdgeInsets.symmetric(horizontal: 20),
          height: 400,
          child: NotificationListener(
            onNotification: (notification) {
              // disable overscroll indicator
              // if (notification is OverscrollIndicatorNotification) {
              //   if (notification.leading) {
              //     notification.disallowGlow();
              //   }
              // }
              if (notification is OverscrollNotification) {
                final dy = notification.overscroll;
                if (dy < 0) {
                  _controller.position.jumpTo(_controller.offset + dy);
                }
              }
              return true;
            },
            child: ListView(
              children: [
                Placeholder(fallbackHeight: 200),
                Placeholder(fallbackHeight: 200),
                Placeholder(fallbackHeight: 200),
                Placeholder(fallbackHeight: 200),
              ],
            ),
          ),
        )
      ],
    );
  }

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