Flutter滚动惯性效果插件scrollable_inertia的使用

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

Flutter滚动惯性效果插件scrollable_inertia的使用

scrollable_inertia

MIT License

一组易于应用的滚动列表自定义设置,使您的Flutter应用程序在众多应用中脱颖而出。

使用方法

每个惯性效果都基于Scrollable(如ListView、SingleChildScrollView、GridView等)能够通知父级小部件当前的速度和轴。InertiaListener 是一个可以拾取这些信息并将它们传递给特定效果以应用基于惯性的动画的小部件。

基于惯性的间距

让列表项受到滚动的影响:

将每个滚动项包裹在InertiaSpacing小部件中,例如:

InertiaListener(
  child: ListView.builder(
    itemBuilder: (_, __) => InertiaSpacing(
      child: YourListItem()
    ),
  ),
)...

动态模糊

让列表项受到滚动的影响:

将整个滚动项包裹在MotionBlur小部件中,例如:

InertiaListener(
  child: MotionBlur(
    child: GridView.builder(...)
  ),
)...

示例代码

以下是一个完整的示例,展示了如何使用scrollable_inertia插件来实现动态间距和动态模糊效果。

import 'dart:math';

import 'package:faker/faker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:scrollable_inertia/scrollable_inertia.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) => MaterialApp(
        title: 'Inertia example',
        theme: ThemeData(
          colorSchemeSeed: Colors.amber,
          useMaterial3: true,
        ),
        home: PageView(
          children: const [
            Page(
              title: '动态间距',
              child: ListWithSpacing(),
            ),
            Page(
              title: '动态模糊',
              child: ListWithMotionBlur(),
            ),
          ],
        ),
      );
}

class Page extends StatelessWidget {
  const Page({
    super.key,
    required this.title,
    required this.child,
  });

  final String title;
  final Widget child;

  void _toggleTimeDilation() {
    timeDilation = timeDilation == 10 ? 1 : 10;
  }

  [@override](/user/override)
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: Text(title),
          actions: [
            IconButton(
              onPressed: _toggleTimeDilation,
              icon: const Icon(Icons.timelapse),
            ),
          ],
        ),
        body: child,
      );
}

class ListWithSpacing extends StatefulWidget {
  const ListWithSpacing({super.key});

  [@override](/user/override)
  State<ListWithSpacing> createState() => _ListWithSpacingState();
}

class _ListWithSpacingState extends State<ListWithSpacing> {
  static const sequence = [
    Alignment.centerLeft,
    Alignment.centerLeft,
    Alignment.centerLeft,
    Alignment.centerLeft,
    Alignment.centerLeft,
    Alignment.centerLeft,
    Alignment.centerRight,
    Alignment.centerRight,
    Alignment.centerRight,
  ];
  final colors = {
    Alignment.centerRight: Colors.amber,
    Alignment.centerLeft: Colors.grey.shade200,
  };
  int seqIterator = 0;

  [@override](/user/override)
  Widget build(BuildContext context) => InertiaListener(
        child: ListView.builder(
          itemBuilder: (context, index) {
            seqIterator = (++seqIterator) % sequence.length;
            return Align(
              alignment: sequence[seqIterator],
              child: InertiaSpacing(
                child: Container(
                  constraints: BoxConstraints(
                      maxWidth: MediaQuery.of(context).size.width * .6),
                  padding: const EdgeInsets.symmetric(
                    vertical: 12,
                    horizontal: 16,
                  ),
                  margin: const EdgeInsets.symmetric(
                    vertical: 1,
                    horizontal: 12,
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(12),
                    color: colors[sequence[seqIterator]],
                  ),
                  child: Text(faker.lorem
                      .sentences(Random().nextInt(2) + 1)
                      .join('. ')),
                ),
              ),
            );
          },
        ),
      );
}

class ListWithMotionBlur extends StatefulWidget {
  const ListWithMotionBlur({super.key});

  [@override](/user/override)
  State<ListWithMotionBlur> createState() => _ListWithMotionBlur();
}

class _ListWithMotionBlur extends State<ListWithMotionBlur> {
  static const _images = [
    'assets/example1.jpg',
    'assets/example2.jpg',
    'assets/example3.jpg',
    'assets/example4.jpg',
    'assets/example5.jpg',
    'assets/example6.jpg',
    'assets/example7.jpg',
    'assets/example8.jpg',
    'assets/example9.jpg',
    'assets/example10.jpg',
  ];
  int seqIterator = 0;

  [@override](/user/override)
  Widget build(BuildContext context) => InertiaListener(
        child: MotionBlur(
          child: GridView.builder(
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 4,
              mainAxisSpacing: 2,
              crossAxisSpacing: 2,
            ),
            itemBuilder: (context, index) => Image.asset(
              _images[seqIterator++ % _images.length],
            ),
          ),
        ),
      );
}

更多关于Flutter滚动惯性效果插件scrollable_inertia的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter滚动惯性效果插件scrollable_inertia的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,scrollable_inertia 是一个用于增强 Flutter 滚动视图惯性效果的插件。它允许开发者在滚动列表或页面时,实现更自然、更流畅的滚动惯性效果。以下是如何在 Flutter 项目中使用 scrollable_inertia 插件的一个示例代码案例。

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

dependencies:
  flutter:
    sdk: flutter
  scrollable_inertia: ^x.y.z  # 请替换为最新版本号

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

接下来,你可以在你的 Flutter 应用中使用 ScrollableInertia 小部件。下面是一个简单的示例,展示如何在 ListView 中应用滚动惯性效果:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Scrollable Inertia Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scrollable Inertia Demo'),
      ),
      body: ScrollableInertia(
        // 惯性参数配置,可以根据需要调整
        inertiaConfig: InertiaConfig(
          friction: 0.01, // 摩擦力系数,值越小惯性越大
          minScrollVelocity: 500.0, // 最小滚动速度
          maxScrollVelocity: 3000.0, // 最大滚动速度
        ),
        child: ListView.builder(
          itemCount: 50,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('Item $index'),
            );
          },
        ),
      ),
    );
  }
}

在这个示例中:

  1. ScrollableInertia 小部件包裹了一个 ListView.builder,它生成了一个包含 50 个条目的列表。
  2. InertiaConfig 类允许你配置惯性效果的参数,比如摩擦力系数 (friction)、最小和最大滚动速度 (minScrollVelocitymaxScrollVelocity)。

你可以根据实际需求调整这些参数,以获得最佳的滚动惯性效果。

请注意,scrollable_inertia 插件的具体 API 和参数可能会随着版本的更新而变化,因此请参考插件的官方文档或源代码以获取最新的信息。

回到顶部