Flutter双滚动视图插件dual_scroll的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter双滚动视图插件dual_scroll的使用

功能特性

  • 该插件可以实现水平和垂直方向的滚动,一旦在某个方向上开始滚动,滚动将被锁定在该方向。
  • 该插件在移动平台上使用触摸手势,在桌面/网页平台上使用鼠标或触控板输入。

注意事项

  • 已移除已停止维护的 synaptics_driver_fix_windows 包。

开始使用

首先,在 pubspec.yaml 文件中添加 dual_scroll 依赖项:

dependencies:
  # 其他依赖项...
  dual_scroll: any
  # 其他依赖项...

然后运行以下命令来获取包:

flutter pub get

使用方法

要使某个小部件可滚动,可以将其包裹在 DualScroll 小部件中:

import 'package:dual_scroll/dual_scroll.dart';

// ...

return DualScroll(
  verticalScrollBar: ScrollBar.defaultScrollBar(),
  horizontalScrollBar: ScrollBar.defaultScrollBar(),
  child: Container(), // 在这里放置你的子小部件
);

与ListView/GridView/可滚动小部件一起使用

如果你希望 DualScroll 的子小部件是 ListViewGridView 或其他可滚动的小部件,可以这样初始化 DualScroll

return DualScroll(
  verticalScrollController: yourVerticalScrollController,
  horizontalScrollController: yourHorizontalScrollController,
  verticalScrollBar: ScrollBar.defaultScrollBar(),
  horizontalScrollBar: ScrollBar.defaultScrollBar(),
  child: Container(), // 在这里放置你的子小部件
);

自定义属性

你可以通过 ScrollBarSettings 来自定义 DualScroll 小部件的属性(不需要提供所有参数):

var scrollBarSettings = ScrollBarSettings(
  keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, // 默认为 ScrollViewKeyboardDismissBehavior.manual
  clipBehavior: Clip.none, // 默认为 Clip.hardEdge
  verticalRestorationId: 'vertId', // 默认为 null
  horizontalRestorationId: 'horizId', // 默认为 null
  verticalPhysics: const ClampingScrollPhysics(), // 默认为 BouncingScrollPhysics
  horizontalPhysics: const ClampingScrollPhysics(), // 默认为 BouncingScrollPhysics
  verticalPadding: const EdgeInsets.all(8.0), // 默认为 null
  horizontalPadding: const EdgeInsets.all(8.0), // 默认为 null
);

return DualScroll(
  // 滚动条和滚动控制器
  settings: scrollBarSettings, // 可选
  pillColor: Colors.blueAccent, // 可选
  dimmedPillColor: Colors.blueAccent.withOpacity(0.8), // 可选
  trackColor: Colors.blueAccent.withOpacity(0.8), // 可选
  trackColorDimmed: Colors.blueAccent.withOpacity(0.6), // 可选
  hoverColor: Colors.blue.withOpacity(0.85), // 可选
  child: child, // 必需
);

完整示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用 dual_scroll 插件:

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

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: DualScroll(
          verticalScrollBar: ScrollBar.defaultScrollBar(),
          horizontalScrollBar: ScrollBar.defaultScrollBar(),
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Container(
              width: 1800,
              height: 2400,
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    Colors.blue,
                    Colors.grey,
                    Colors.green,
                    Colors.purple,
                  ],
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                ),
              ),
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

更多关于Flutter双滚动视图插件dual_scroll的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter双滚动视图插件dual_scroll的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,dual_scroll 是一个用于在 Flutter 中实现双滚动视图的插件。这个插件允许你在一个屏幕上同时使用两个滚动视图,例如一个侧边栏菜单和一个主内容区域,并且这两个滚动视图可以独立滚动,互不干扰。

以下是一个简单的示例代码,展示了如何使用 dual_scroll 插件来实现双滚动视图。

首先,确保你已经在 pubspec.yaml 文件中添加了 dual_scroll 依赖:

dependencies:
  flutter:
    sdk: flutter
  dual_scroll: ^最新版本号  # 请替换为实际最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在你的 Dart 文件中使用 DualScrollView 来构建双滚动视图。以下是一个完整的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dual Scroll View Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dual Scroll View Example'),
        ),
        body: DualScrollView(
          controller: DualScrollController(),
          sliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              // 左侧栏(SliverPersistentHeader 示例)
              SliverPersistentHeader(
                delegate: _SliverAppBarDelegate(
                  minHeight: 60.0,
                  maxHeight: 200.0,
                  child: Container(
                    color: Colors.blue,
                    alignment: Alignment.center,
                    child: Text(
                      'Sidebar',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
                pinned: true,
              ),
              // 左侧栏内容(SliverList 示例)
              SliverList(
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return ListTile(
                      title: Text('Sidebar Item $index'),
                    );
                  },
                  childCount: 20,
                ),
              ),
              // 分隔符
              SliverToBoxAdapter(
                child: Divider(
                  thickness: 2.0,
                ),
              ),
              // 主内容区域(SliverGrid 示例)
              SliverGrid(
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200.0,
                  crossAxisSpacing: 10.0,
                  mainAxisSpacing: 10.0,
                ),
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Container(
                      color: Colors.amber[index % 10 * 100],
                      child: Center(
                        child: Text('Grid Item $index'),
                      ),
                    );
                  },
                  childCount: 100,
                ),
              ),
            ];
          },
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    required this.minHeight,
    required this.maxHeight,
    required this.child,
  });

  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => maxHeight;

  @override
  Widget build(
    BuildContext context,
    double shrinkOffset,
    bool overlapsContent,
  ) {
    return SizedBox.expand(
      child: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          Positioned.fill(
            child: Container(
              color: Colors.transparent,
            ),
          ),
          if (shrinkOffset > 0.0)
            Positioned(
              bottom: 0.0,
              left: 0.0,
              right: 0.0,
              height: maxHeight - shrinkOffset,
              child: child,
            )
          else
            child,
        ],
      ),
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return minHeight != oldDelegate.minHeight ||
        maxHeight != oldDelegate.maxHeight ||
        child != oldDelegate.child;
  }
}

在这个示例中,我们创建了一个 DualScrollView,它包含了一个侧边栏和一个主内容区域。侧边栏使用了 SliverPersistentHeaderSliverList 来展示固定头部和列表项,而主内容区域使用了 SliverGrid 来展示网格项。

你可以根据实际需求对侧边栏和主内容区域的内容进行自定义。这个示例只是一个基本的框架,展示了如何使用 dual_scroll 插件来实现双滚动视图。

回到顶部