Flutter分页展示插件shelf_paginate的使用

Flutter分页展示插件shelf_paginate的使用

在本教程中,我们将介绍如何使用shelf_paginate插件来实现一个分页展示的功能。shelf_paginate是一个基于Dart的分页中间件,它可以帮助我们在后端处理分页逻辑,并将数据返回给前端。

安装shelf_paginate

首先,在你的pubspec.yaml文件中添加shelf_paginate依赖:

dependencies:
  shelf_paginate: ^x.x.x

然后运行flutter pub get以安装该包。

使用shelf_paginate

后端设置

首先,我们需要创建一个API来处理分页请求。以下是一个简单的例子,展示了如何使用shelf_paginate来实现分页功能。

import 'dart:convert';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_paginate/shelf_paginate.dart';

const API_URL = 'www.api_shelf_paginate.com/start?page=1&limit=2';
const Map<String, Object?> header = {'x-paginate': 'true'};

void main() async {
  var handler =
      const Pipeline()
        .addMiddleware(logRequests())
        .addMiddleware(shelPaginate(maxlimit: 100))
        .addHandler(_paginateRequest);

  var server = await shelf_io.serve(handler, 'localhost', 8080);

  print('Serving at http://${server.address.host}:${server.port}');
}

Response _paginateRequest(Request request) =>
    return Response.ok(jsonEncode([
      {
        "id": 1,
        "name": "梅西",
        "club": "巴黎圣日耳曼",
      },
      {
        "id": 2,
        "name": "姆巴佩",
        "club": "巴黎圣日耳曼",
      },
      {
        "id": 3,
        "name": "穆罕默德·萨拉赫",
        "club": "利物浦",
      },
      {
        "id": 4,
        "name": "克里斯蒂亚诺·罗纳尔多",
        "club": "曼联",
      },
      {
        "id": 5,
        "name": "格里兹曼",
        "club": "马德里竞技",
      },
      {
        "id": 6,
        "name": "博格巴",
        "club": "尤文图斯",
      }
    ]));

在这个例子中,我们定义了一个API URL,用于接收分页参数(如pagelimit)。shelf_paginate中间件会检查请求头中的x-paginate字段,并根据pagelimit参数从数据库或其他数据源获取相应分页的数据。

前端展示

接下来,我们需要在Flutter前端展示这些分页数据。我们可以使用ListView.builder来动态生成列表项。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class PlayerList extends StatefulWidget {
  [@override](/user/override)
  _PlayerListState createState() => _PlayerListState();
}

class _PlayerListState extends State<PlayerList> {
  List<dynamic> players = [];
  int currentPage = 1;
  int pageSize = 2;

  Future<void> fetchPlayers() async {
    final response = await http.get(Uri.parse(
        'http://localhost:8080/start?page=$currentPage&limit=$pageSize'));
    if (response.statusCode == 200) {
      setState(() {
        players = jsonDecode(response.body);
      });
    } else {
      throw Exception('Failed to load players');
    }
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    fetchPlayers();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('球员列表'),
      ),
      body: ListView.builder(
        itemCount: players.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(players[index]['name']),
            subtitle: Text(players[index]['club']),
          );
        },
      ),
    );
  }
}

更多关于Flutter分页展示插件shelf_paginate的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter分页展示插件shelf_paginate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


shelf_paginate 是一个用于 Dart 服务器端框架 shelf 的分页插件,它可以帮助你轻松地实现分页功能。虽然 shelf_paginate 不是专门为 Flutter 设计的,但你可以在 Flutter 应用中通过调用后端 API 来使用它。下面是如何在 shelf 中使用 shelf_paginate 的示例,以及如何在 Flutter 中进行分页展示。

1. 安装 shelf_paginate

首先,在你的 Dart 服务器项目中安装 shelf_paginate

dependencies:
  shelf: ^1.0.0
  shelf_paginate: ^1.0.0

然后运行 pub get 来安装依赖。

2. 在 shelf 中使用 shelf_paginate

假设你有一个返回列表数据的 API,并希望对其进行分页。以下是一个简单的示例:

import 'package:shelf/shelf.dart';
import 'package:shelf_paginate/shelf_paginate.dart';
import 'package:shelf_router/shelf_router.dart';

void main() {
  var app = Router();

  // 模拟数据
  final items = List.generate(100, (index) => 'Item ${index + 1}');

  // 分页路由
  app.get('/items', (Request request) {
    return paginate(
      request,
      items,
      pageSize: 10, // 每页显示10条数据
      serializer: (List<String> pageItems, int pageNumber, int totalPages) {
        return {
          'page': pageNumber,
          'total_pages': totalPages,
          'data': pageItems,
        };
      },
    );
  });

  // 启动服务器
  var server = await shelf_io.serve(app, 'localhost', 8080);
  print('Server running on localhost:${server.port}');
}

在这个示例中,paginate 函数会根据 request 中的查询参数(通常是 pageperPage)对 items 列表进行分页,并返回分页后的结果。

3. 在 Flutter 中调用 API 并展示分页数据

在 Flutter 中,你可以使用 http 包或其他网络库来调用这个 API,并展示分页数据。以下是一个简单的 Flutter 示例:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Pagination Demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<String> items = [];
  int currentPage = 1;
  int totalPages = 1;

  Future<void> fetchItems(int page) async {
    final response = await http.get(Uri.parse('http://localhost:8080/items?page=$page'));

    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      setState(() {
        items = List<String>.from(data['data']);
        currentPage = data['page'];
        totalPages = data['total_pages'];
      });
    } else {
      throw Exception('Failed to load items');
    }
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    fetchItems(1);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Pagination Demo'),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: items.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(items[index]),
                );
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButton(
                  icon: Icon(Icons.arrow_back),
                  onPressed: currentPage > 1
                      ? () {
                          fetchItems(currentPage - 1);
                        }
                      : null,
                ),
                Text('Page $currentPage of $totalPages'),
                IconButton(
                  icon: Icon(Icons.arrow_forward),
                  onPressed: currentPage < totalPages
                      ? () {
                          fetchItems(currentPage + 1);
                        }
                      : null,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
回到顶部