如何在Flutter中同时滚动两个SingleChildScrollView?

lkaoscv7  于 2022-12-05  发布在  Flutter
关注(0)|答案(3)|浏览(412)

我要同时垂直滚动两个SingleChildScrollView

omtl5h9j

omtl5h9j1#

此代码适用于两个SingleChildScrollView。

import 'package:flutter/material.dart';

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

  @override
  State<ScrollTestPage> createState() => _ScrollTestPageState();
}

class _ScrollTestPageState extends State<ScrollTestPage> {
  final _controller1 = ScrollController();
  final _controller2 = ScrollController();

  @override
  void initState() {
    super.initState();
    _controller1.addListener(listener1);
    _controller2.addListener(listener2);
  }

  var _flag1 = false;
  var _flag2 = false;

  void listener1() {
    if (_flag2) return;
    _flag1 = true;
    _controller2.jumpTo(_controller1.offset);
    _flag1 = false;
  }

  void listener2() {
    if (_flag1) return;
    _flag2 = true;
    _controller1.jumpTo(_controller2.offset);
    _flag2 = false;
  }

  @override
  void dispose() {
    super.dispose();
    _controller1.removeListener(listener1);
    _controller2.removeListener(listener2);
    _controller1.dispose();
    _controller2.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              controller: _controller1,
              itemBuilder: (context, i) {
                return Container(
                  margin: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                  child: Text('First List View $i'),
                );
              },
              itemCount: 100,
            ),
          ),
          Expanded(
            child: ListView.builder(
              controller: _controller2,
              itemBuilder: (context, i) {
                return Container(
                  margin: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                  child: Text('Second List View $i'),
                );
              },
              itemCount: 100,
            ),
          ),
        ],
      ),
    );
  }
}
1sbrub3j

1sbrub3j2#

您可以将两个SingleChildScrollView小部件的controller:参数设置为同一个控制器。控制器必须按如下方式初始化:

final ScrollController _scrollController = ScrollController();
djmepvbi

djmepvbi3#

针对这种情况,Google开发人员自己开发了一个包(https://pub.dev/packages/linked_scroll_controller)。它很容易使用。初始化链接的滚动控制器,并将滚动控制器连接到链接的滚动控制器。然后将这些控制器传递到您想要同步滚动的可滚动部件。

import 'package:flutter/material.dart';
import 'package:linked_scroll_controller/linked_scroll_controller.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'List',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: const List(),
    );
  }
}

class List extends StatefulWidget {
  const List({Key? key}) : super(key: key);
  @override
  _ListState createState() => _ListState();
}

class _ListState extends State<List> {
  late LinkedScrollControllerGroup _controllers; // Declare link scroll Controller
  late ScrollController _letters; // Declare scroll controller for first list/widget
  late ScrollController _numbers; // Declare scroll controller for second list/widget

  @override
  void initState() {
    super.initState();
    _controllers = LinkedScrollControllerGroup(); // Initialize link scroll controller 
    _letters = _controllers.addAndGet(); // Attach the first list/widget scroll controller to link scroll controller 
    _numbers = _controllers.addAndGet(); // Attach the second list/widget scroll controller to link scroll controller
  }

  @override
  void dispose() {
    _letters.dispose();
    _numbers.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: Column(
          children: [
            Expanded(
              child: ListView.builder(
                controller: _letters, // First list/widget scroll controller
                itemBuilder: (context, i) {
                  return Container(
                    margin: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                    child: Text('First List View $i'),
                  );
                },
                itemCount: 100,
              ),
            ),
            Expanded(
              child: ListView.builder(
                controller: _numbers, // Second list/widget scroll controller
                itemBuilder: (context, i) {
                  return Container(
                    margin: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                    child: Text('Second List View $i'),
                  );
                },
                itemCount: 100,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _Tile extends StatelessWidget {
  final String caption;

  _Tile(this.caption);

  @override
  Widget build(_) => Container(
        margin: const EdgeInsets.all(8.0),
        padding: const EdgeInsets.all(8.0),
        height: 250.0,
        child: Center(child: Text(caption)),
      );
}

相关问题