Flutter可滚动组件插件scrollable的使用

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

Flutter可滚动组件插件scrollable的使用

Flutter中的scrollable插件提供了一套强大的可滚动组件,包括触觉反馈、软键盘自动收起等功能。以下是关于如何使用这个插件的详细说明和一个完整的示例demo。

一、插件功能介绍

1. 插件包含3个主要组件

  • ScrollHaptics:在子组件滚动时(滚动期间及到达滚动视图边缘时)应用触觉反馈。
  • KeyboardDismiss:当其子组件被滚动、点击或滑动时,关闭软键盘。
  • ScrollableView:将上述两个组件的功能整合到一个组件中,便于使用。

2. 示例Gif展示

Example Gif

注意:虽然gif难以显示触觉反馈效果,但实际使用中确实存在。

二、安装与快速开始

1. 安装

通过以下命令从pub.dev安装scrollable插件:

flutter pub add scrollable

然后在Dart文件顶部导入包:

import 'package:scrollable/exports.dart';

2. 快速开始

只需将需要包裹的内容放入ScrollHapticsKeyboardDismissScrollableView中,并根据需求调整它们的属性即可。

三、三个组件的简短示例

ScrollHaptics

ScrollHaptics(
  child: SingleChildScrollView(
    child: Column(
      children: [
        Container(height: 100, width: 100, color: Colors.redAccent),
        Container(height: 100, width: 100, color: Colors.blue),
        Container(height: 100, width: 100, color: Colors.purple),
      ],
    ),
  ),
);

KeyboardDismiss

KeyboardDismiss(
  child: SingleChildScrollView(
    child: Column(
      children: [
        Container(height: 100, width: 100, color: Colors.redAccent),
        Container(height: 100, width: 100, color: Colors.blue),
        Container(height: 100, width: 100, color: Colors.purple),
      ],
    ),
  ),
);

ScrollableView

ScrollableView(
  controller: ScrollController(),
  child: SingleChildScrollView(
    child: Column(
      children: [
        Container(height: 100, width: 100, color: Colors.redAccent),
        Container(height: 100, width: 100, color: Colors.blue),
        Container(height: 100, width: 100, color: Colors.purple),
      ],
    ),
  ),
);

四、完整示例代码

下面是一个更完整的示例,它展示了如何结合使用ScrollableView来实现带有触觉反馈和软键盘自动收起功能的页面:

import 'package:flutter/material.dart';
import 'package:scrollable/exports.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Demo",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomeScreen(),
    );
  }
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final ScrollController controller = ScrollController();

  @override
  void dispose() {
    controller.dispose(); // 记得释放控制器资源
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Includes haptics (hard to show)"),
      ),
      body: ScrollableView(
        controller: controller,
        child: SingleChildScrollView(
          physics: const ClampingScrollPhysics(), // 推荐使用ClampingScrollPhysics以获得更好的触觉体验
          controller: controller,
          child: Column(
            children: [
              Container(
                width: double.infinity,
                color: Colors.blue,
                child: const Align(
                  alignment: Alignment.topCenter,
                  child: Text(
                    "^ Inline padding. This allows the ScrollableView to have an 'in-scroll' offset, instead of having to wrap the outside of the scroll view with padding, or filling it with SizedBoxes. At bottom too.",
                    style: TextStyle(color: Colors.white, fontSize: 25),
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
              Container(width: double.infinity, height: 150, color: Colors.red),
              Container(width: double.infinity, height: 150, color: Colors.green),
              Container(width: double.infinity, height: 150, color: Colors.pink),
              Container(
                width: double.infinity,
                color: Colors.white,
                child: Column(
                  children: [
                    const Text(
                      "Example textfield to open keyboard, and show it closes on scroll (or tap).",
                      textAlign: TextAlign.center,
                      style: TextStyle(fontSize: 35),
                    ),
                    TextFormField(
                      decoration: const InputDecoration(
                        hintText: "Example textfield.",
                      ),
                    ),
                  ],
                ),
              ),
              Container(width: double.infinity, height: 150, color: Colors.purple),
              Container(width: double.infinity, height: 150, color: Colors.cyan),
              Container(width: double.infinity, height: 150, color: Colors.brown),
              Container(width: double.infinity, height: 150, color: Colors.orangeAccent),
              Container(width: double.infinity, height: 150, color: Colors.lightGreen),
              Container(width: double.infinity, height: 150, color: Colors.yellowAccent),
            ],
          ),
        ),
      ),
    );
  }
}

此示例创建了一个包含多个容器的颜色条带,并且添加了一个文本输入框用于演示软键盘自动收起功能。同时,整个页面都启用了触觉反馈效果。希望这些信息能帮助你更好地理解和使用scrollable插件!


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

1 回复

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


在Flutter中,Scrollable 是一个抽象类,通常不会直接使用它,而是通过它的具体实现类如 ListViewGridViewSingleChildScrollView 等来实现滚动功能。这些组件内部都使用了 Scrollable 提供的滚动机制。

以下是一些常见的可滚动组件的使用示例:

1. ListView

ListView 是最常用的可滚动组件之一,用于显示线性排列的子组件列表。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView Example'),
        ),
        body: ListView(
          children: List.generate(
            20,
            (index) => ListTile(
              title: Text('Item $index'),
            ),
          ),
        ),
      ),
    );
  }
}

2. GridView

GridView 用于显示网格布局的子组件列表。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('GridView Example'),
        ),
        body: GridView.count(
          crossAxisCount: 3,
          children: List.generate(
            20,
            (index) => Card(
              child: Center(
                child: Text('Item $index'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

3. SingleChildScrollView

SingleChildScrollView 用于包装一个单独的、较大的子组件,使其可以垂直或水平滚动。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('SingleChildScrollView Example'),
        ),
        body: SingleChildScrollView(
          child: Column(
            children: List.generate(
              50,
              (index) => ListTile(
                title: Text('Item $index'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

4. CustomScrollView

CustomScrollView 允许你创建更加复杂的滚动视图,通过 Sliver 子组件来实现。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('CustomScrollView Example'),
        ),
        body: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              title: Text('SliverAppBar'),
              pinned: true,
              expandedHeight: 200,
              flexibleSpace: FlexibleSpaceBar(
                background: Image.network(
                  'https://via.placeholder.com/600x200',
                  fit: BoxFit.cover,
                ),
              ),
            ),
            SliverList(
              delegate: SliverChildListDelegate(
                List.generate(
                  20,
                  (index) => ListTile(
                    title: Text('Item $index'),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

这些示例展示了如何使用不同的可滚动组件来实现滚动功能。根据具体需求,你可以选择适合的可滚动组件,并通过调整其属性来满足你的布局需求。

回到顶部