Flutter自定义滚动视图插件basescrollview的使用

Flutter自定义滚动视图插件basescrollview的使用

Getting Started(开始)

请仔细阅读下面的示例代码!


示例代码

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'package:basescrollview/basescrollview.dart';

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

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
    _getData();
  }

  bool _isLoading = true;
  bool _isLoadMore = false;

  Timer? _timer;

  final int _maxRow = 50;
  int _index = 1;

  List<String> _items = [];

  void _startTimer() {
    _timer?.cancel();
    _timer = Timer.periodic(const Duration(seconds: 3), (timer) {
      setState(() {
        _isLoading = false;
      });
    });
  }

  void _getData({bool isReload = true}) {
    if (_items.length == _maxRow && !isReload) return;
    _isLoading = isReload;
    if (isReload) {
      _index = 1;
    }
    if (_index == 1) {
      _items = List<String>.generate(10, (index) => index.toString());
    } else {
      int i = 0;
      while(i < 10) {
        _items.add(_items.length.toString());
        i += 1;
      }
    }
    _isLoadMore = _items.length < _maxRow;
    if (_isLoadMore) {
      _index += 1;
    }
    setState(() {});
    _startTimer();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('BaseScrollView'),
        ),
        body: BaseScrollView(
          isEnableRefreshIndicator: false, // 是否启用刷新指示器
          indicatorColor: Colors.black87, // 刷新指示器颜色
          indicatorActiveColor: Colors.blue, // 刷新指示器活动颜色
          imageLoading: 'assets/images/loading.svg', // 加载中的图像
          loadingString: 'Loading...', // 加载中的文本
          angle: pi / 2, // 加载动画的角度
          style: LoadingStyle.rotateAndopacity, // 加载动画样式
          onRefresh: _onScrollToTop, // 刷新回调
          onLoadMore: _onScrollToBottom, // 加载更多回调
          onScrollUpdate: _onScrollUpdate, // 滚动更新回调
          isLoading: true, // 是否正在加载
          child: LayoutBuilder(
            builder: (context, constraints) => ListView.builder(
              padding: const EdgeInsets.all(16.0),
              physics: const AlwaysScrollableScrollPhysics(), // 确保可以滚动
              itemCount: _items.length + (_items.isNotEmpty ? 1 : 0), // 项目数量
              itemBuilder: (context, index) => index < _items.length ? Container(
                  height: constraints.maxHeight / 10 - 10,
                  width: double.infinity,
                  decoration: BoxDecoration(
                    color: Colors.grey.shade400,
                    borderRadius: BorderRadius.circular(16),
                  ),
                  margin: const EdgeInsets.only(bottom: 10),
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child: Center(child: Text('Item ${_items[index]}')),
                  ),
                ) : _items.length > 9 ? Container(
                  padding: const EdgeInsets.all(10),
                  child: Center(
                    child: _isLoadMore
                        ? SizedBox(
                            width: 24,
                            height: 24,
                            child: CircularProgressIndicator(
                              color: Colors.blue.shade100,
                              backgroundColor: Colors.blue.shade600,
                            ),
                          )
                        : const Text("That's all!"),
                  ),
                ) : const SizedBox(),
            ),
          ),
        ),
      ),
    );
  }

  Future<void> _onScrollToTop() async {
    print('_onScrollToTop');
    _getData();
  }

  Future<void> _onScrollUpdate(ScrollDirection scrollDirection, double position) async {
    print('_onUpdateScroll direction $scrollDirection at $position');
  }

  Future<void> _onScrollToBottom() async {
    print('_onScrollToBottom');
    _getData(isReload: false);
  }
}

代码解释

  1. 导入必要的库

    import 'dart:math';
    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    import 'dart:async';
    import 'package:basescrollview/basescrollview.dart';
    
  2. 初始化应用

    void main() {
      runApp(const MyApp());
    }
    
  3. 创建主应用类

    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      [@override](/user/override)
      State<MyApp> createState() => _MyAppState();
    }
    
  4. 初始化数据

    class _MyAppState extends State<MyApp> {
      [@override](/user/override)
      void initState() {
        super.initState();
        _getData();
      }
    
  5. 定义变量

    bool _isLoading = true;
    bool _isLoadMore = false;
    
    Timer? _timer;
    
    final int _maxRow = 50;
    int _index = 1;
    
    List<String> _items = [];
    
  6. 启动定时器

    void _startTimer() {
      _timer?.cancel();
      _timer = Timer.periodic(const Duration(seconds: 3), (timer) {
        setState(() {
          _isLoading = false;
        });
      });
    }
    
  7. 获取数据

    void _getData({bool isReload = true}) {
      if (_items.length == _maxRow && !isReload) return;
      _isLoading = isReload;
      if (isReload) {
        _index = 1;
      }
      if (_index == 1) {
        _items = List<String>.generate(10, (index) => index.toString());
      } else {
        int i = 0;
        while(i < 10) {
          _items.add(_items.length.toString());
          i += 1;
        }
      }
      _isLoadMore = _items.length < _maxRow;
      if (_isLoadMore) {
        _index += 1;
      }
      setState(() {});
      _startTimer();
    }
    
  8. 构建UI

    [@override](/user/override)
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('BaseScrollView'),
          ),
          body: BaseScrollView(
            isEnableRefreshIndicator: false, // 是否启用刷新指示器
            indicatorColor: Colors.black87, // 刷新指示器颜色
            indicatorActiveColor: Colors.blue, // 刷新指示器活动颜色
            imageLoading: 'assets/images/loading.svg', // 加载中的图像
            loadingString: 'Loading...', // 加载中的文本
            angle: pi / 2, // 加载动画的角度
            style: LoadingStyle.rotateAndopacity, // 加载动画样式
            onRefresh: _onScrollToTop, // 刷新回调
            onLoadMore: _onScrollToBottom, // 加载更多回调
            onScrollUpdate: _onScrollUpdate, // 滚动更新回调
            isLoading: true, // 是否正在加载
            child: LayoutBuilder(
              builder: (context, constraints) => ListView.builder(
                padding: const EdgeInsets.all(16.0),
                physics: const AlwaysScrollableScrollPhysics(), // 确保可以滚动
                itemCount: _items.length + (_items.isNotEmpty ? 1 : 0), // 项目数量
                itemBuilder: (context, index) => index < _items.length ? Container(
                    height: constraints.maxHeight / 10 - 10,
                    width: double.infinity,
                    decoration: BoxDecoration(
                      color: Colors.grey.shade400,
                      borderRadius: BorderRadius.circular(16),
                    ),
                    margin: const EdgeInsets.only(bottom: 10),
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Center(child: Text('Item ${_items[index]}')),
                    ),
                  ) : _items.length > 9 ? Container(
                    padding: const EdgeInsets.all(10),
                    child: Center(
                      child: _isLoadMore
                          ? SizedBox(
                              width: 24,
                              height: 24,
                              child: CircularProgressIndicator(
                                color: Colors.blue.shade100,
                                backgroundColor: Colors.blue.shade600,
                              ),
                            )
                          : const Text("That's all!"),
                    ),
                  ) : const SizedBox(),
              ),
            ),
          ),
        ),
      );
    }
    
  9. 处理滚动事件

    Future<void> _onScrollToTop() async {
      print('_onScrollToTop');
      _getData();
    }
    
    Future<void> _onScrollUpdate(ScrollDirection scrollDirection, double position) async {
      print('_onUpdateScroll direction $scrollDirection at $position');
    }
    
    Future<void> _onScrollToBottom() async {
      print('_onScrollToBottom');
      _getData(isReload: false);
    }
    

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

1 回复

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


BaseScrollView 是一个用于 Flutter 的自定义滚动视图插件,它提供了比默认的 ListViewGridView 更灵活的滚动行为。使用 BaseScrollView,你可以实现自定义的滚动效果、布局和交互。

以下是如何使用 BaseScrollView 的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 basescrollview 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  basescrollview: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 以安装依赖。

2. 导入插件

在你的 Dart 文件中导入 basescrollview

import 'package:basescrollview/basescrollview.dart';

3. 使用 BaseScrollView

BaseScrollView 的使用方式与 ListViewGridView 类似,但它提供了更多的自定义选项。

基本用法

BaseScrollView(
  child: Column(
    children: [
      // 你的子部件
      Container(
        height: 200,
        color: Colors.red,
      ),
      Container(
        height: 200,
        color: Colors.green,
      ),
      Container(
        height: 200,
        color: Colors.blue,
      ),
    ],
  ),
);

自定义滚动行为

你可以通过 scrollControllerphysics 来自定义滚动行为:

final ScrollController _scrollController = ScrollController();

BaseScrollView(
  controller: _scrollController,
  physics: BouncingScrollPhysics(), // 使用回弹效果
  child: Column(
    children: [
      // 你的子部件
      Container(
        height: 200,
        color: Colors.red,
      ),
      Container(
        height: 200,
        color: Colors.green,
      ),
      Container(
        height: 200,
        color: Colors.blue,
      ),
    ],
  ),
);

添加滚动监听

你可以通过 onScroll 回调来监听滚动事件:

BaseScrollView(
  onScroll: (ScrollPosition position) {
    print('Scroll position: ${position.pixels}');
  },
  child: Column(
    children: [
      // 你的子部件
      Container(
        height: 200,
        color: Colors.red,
      ),
      Container(
        height: 200,
        color: Colors.green,
      ),
      Container(
        height: 200,
        color: Colors.blue,
      ),
    ],
  ),
);

自定义布局

BaseScrollView 允许你通过 builder 来自定义布局:

BaseScrollView.builder(
  itemBuilder: (BuildContext context, int index) {
    return Container(
      height: 100,
      color: index % 2 == 0 ? Colors.red : Colors.blue,
      child: Center(
        child: Text('Item $index'),
      ),
    );
  },
  itemCount: 20,
);

4. 其他功能

BaseScrollView 还支持其他一些功能,例如:

  • 分页加载:你可以通过 onLoadMore 回调来实现分页加载。
  • 下拉刷新:通过 refreshIndicator 来实现下拉刷新功能。

示例代码

以下是一个完整的示例,展示了如何使用 BaseScrollView 实现一个简单的滚动视图:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('BaseScrollView Example'),
        ),
        body: BaseScrollView(
          child: Column(
            children: List.generate(
              20,
              (index) => Container(
                height: 100,
                color: index % 2 == 0 ? Colors.red : Colors.blue,
                child: Center(
                  child: Text('Item $index'),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
回到顶部