简体   繁体   中英

how to scroll two listview builder simultaneously inside the pageview builder

我在 pageViewbuilder 中添加了两个列表视图构建器,这两个列表视图可以单独滚动,但我希望这两个列表视图可以同时滚动

The solution is to synchronize the scroll between two ListView s by listening to scroll events with NotificationListener<ScrollNotification> . Whenever a scroll event is emitted from one ListView set the other ListView controller to jump to the same position.

One optimization is to ignore notifications on the other ListView if the first or second one is already scrolling. But it also works without this optimization.

This is the result (Check also out the live demo on DartPad ).

截屏

Sources:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

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

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

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

enum ScrollingList {
  none,
  left,
  right,
}

class _MyHomePageState extends State {
  late final ScrollController _controllerLeft;
  late final ScrollController _controllerRight;
  var scrollingList = ScrollingList.none;

  @override
  void initState() {
    super.initState();
    _controllerLeft = ScrollController();
    _controllerRight = ScrollController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          Expanded(
            child: NotificationListener<ScrollNotification>(
              onNotification: (notification) {
                if (notification is ScrollStartNotification) {
                  if (scrollingList == ScrollingList.none) {
                    scrollingList = ScrollingList.left;
                  }
                } else if (notification is ScrollEndNotification) {
                  if (scrollingList == ScrollingList.left) {
                    scrollingList = ScrollingList.none;
                  }
                }
                if (scrollingList == ScrollingList.left) {
                  _controllerRight.jumpTo(_controllerLeft.offset);
                }
                return true;
              },
              child: ListView.separated(
                controller: _controllerLeft,
                itemBuilder: (context, index) {
                  return Text('Item a$index');
                },
                separatorBuilder: (context, index) {
                  return const Divider();
                },
                itemCount: 100,
              ),
            ),
          ),
          const VerticalDivider(),
          Expanded(
            child: NotificationListener<ScrollNotification>(
              onNotification: (notification) {
                if (notification is ScrollStartNotification) {
                  if (scrollingList == ScrollingList.none) {
                    scrollingList = ScrollingList.right;
                  }
                } else if (notification is ScrollEndNotification) {
                  if (scrollingList == ScrollingList.right) {
                    scrollingList = ScrollingList.none;
                  }
                }
                if (scrollingList == ScrollingList.right) {
                  _controllerLeft.jumpTo(_controllerRight.offset);
                }
                return true;
              },
              child: ListView.separated(
                controller: _controllerRight,
                itemBuilder: (context, index) {
                  return Text('Item b$index');
                },
                separatorBuilder: (context, index) {
                  return const Divider();
                },
                itemCount: 100,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM