fluent_refresher 1.0.1 copy "fluent_refresher: ^1.0.1" to clipboard
fluent_refresher: ^1.0.1 copied to clipboard

A powerful and easy-to-use pull-to-refresh and pull-up-to-load package for Flutter, providing a fluent user experience.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fluent Refresher Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyPage(),
    );
  }
}


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

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  // 创建控制器
  final _controller = RefreshController();
  List<Map<String, dynamic>> _items = [];

  @override
  void initState() {
    super.initState();
    // 初始加载数据
    _items = _generateItems(200);
  }

  // 辅助函数:生成带图片和文本的数据
  List<Map<String, dynamic>> _generateItems(int count, {int offset = 0}) {
    return List.generate(count, (i) {
      final index = i + offset;
      return {
        'id': index,
        'title': '项目标题 ${index + 1}',
        'subtitle': '这是一个关于项目${index + 1}的详细描述内容。',
        // 使用 picsum.photos 获取随机图片,用 id 作为 seed 保证图片稳定
        'imageUrl': 'https://picsum.photos/seed/${index + 1}/200/200',
      };
    });
  }

  // 定义刷新回调
  Future<void> _onRefresh() async {
    // 模拟网络请求
    await Future.delayed(const Duration(milliseconds: 500));
    if (!mounted) return;

    setState(() {
      _items = _generateItems(150);
    });
    // 刷新成功后,重置加载状态,以便可以再次上拉加载
    _controller.refreshCompleted();
  }

  // 定义加载回调
  Future<void> _onLoading() async {
    // 模拟网络请求
    await Future.delayed(const Duration(milliseconds: 500));
    if (!mounted) return;

    final newItems = _generateItems(100, offset: _items.length);
    setState(() {
      _items.addAll(newItems);
    });

    // 使用控制器更新 Footer 状态
    if (newItems.isEmpty || _items.length >= 1000) {
      // 如果没有更多数据了
      _controller.loadNoData();
    } else {
      // 加载成功
      _controller.loadComplete();
    }
  }

  @override
  void dispose() {
    // 销毁控制器
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('fluent_refresher demo')),
      // 使用工厂函数构造
      body: FluentRefresher.builder(
        controller: _controller,
        enablePullDown: true,
        enablePullUp: true,
        onRefresh: _onRefresh,
        onLoading: _onLoading,
        itemCount: _items.length,
        itemBuilder: (context , index){
          final item = _items[index];
          return _buildCard(item);
        },
      ),

      // 普通构造函数
      // body: FluentRefresher(
      //   controller: _controller,
      //   enablePullDown: true,
      //   enablePullUp: true,
      //   onRefresh: _onRefresh,
      //   onLoading: _onLoading,
      //   headerTriggerDistance: 40.0,
      //   sliver: SliverList(
      //     delegate: SliverChildBuilderDelegate((context, index) {
      //       final item = _items[index];
      //       return _buildCard(item);
      //     },
      //     childCount: _items.length,
      //     ),
      //   ),
      // ),
    );
  }

  Widget _buildCard(Map<String, dynamic> item){
    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      elevation: 4,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      child: Padding(
        padding: const EdgeInsets.all(12.0),
        child: Row(
          children: [
            ClipRRect(
              borderRadius: BorderRadius.circular(8.0),
              child: Image.network(
                item['imageUrl'],
                width: 80,
                height: 80,
                fit: BoxFit.cover,
                loadingBuilder: (context, child, progress) =>
                progress == null ? child : const Center(child: CircularProgressIndicator()),
                errorBuilder: (context, error, stackTrace) =>
                const Icon(Icons.error, size: 40, color: Colors.red),
              ),
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(item['title'], style: Theme.of(context).textTheme.titleMedium),
                  const SizedBox(height: 8),
                  Text(item['subtitle'], style: Theme.of(context).textTheme.bodySmall),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
145
points
28
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A powerful and easy-to-use pull-to-refresh and pull-up-to-load package for Flutter, providing a fluent user experience.

Repository

License

MIT (license)

Dependencies

flutter, meta

More

Packages that depend on fluent_refresher