【问题标题】:Load more option in flutter ListView在 Flutter ListView 中加载更多选项
【发布时间】:2021-03-19 17:42:48
【问题描述】:

我想部分获取所有无限列表视图数据,这意味着最初它加载 10 个数据项,并且在滚动更多时它应该获取接下来的 10 个项目。 我正在从我的 Laravel api 获取数据,并且在我的 Laravel api 端点中没有 per_page 选项,所以请帮助我集成加载更多列表视图数据的选项。 这是我的列表数据。

List<Category> _categoryList = List<Category>();
  CategoryService _categoryService = CategoryService();

  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    _getAllCategories();
  }
  _getAllCategories() async {
    var categories = await _categoryService.getCategories();
    var result = json.decode(categories.body);
    result['data'].forEach((data) {
      var model = Category();
      model.id = data["id"];
      model.name = data["categoryName"];
      model.icon = data["categoryIcon"];
      setState(() {
        _categoryList.add(model);
        isLoading = false;
      });
    });
  }

我正在简单的 ListTile 中获取所有数据。

child: ListView.builder(
        itemCount: //_categoryList.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: _categoryList.name
          );
        },
      ),

【问题讨论】:

标签: android flutter dart flutter-layout


【解决方案1】:

所以我有一个技巧,我正在我的项目中使用它。我们需要的是在列表末尾时加载更多数据。因此,我们只能使用ListView.builder()


child: ListView.builder(
       itemCount: _categoryList.length + 1,
       itemBuilder: (context, index) {
         if(index == _categoryList.length){
          // loadMore();
          // return Loading();         
          }
         return ListTile(
            title: _categoryList.name
          );
       }),

所以我们正在做的是将_categoryList.length + 1 设置为itemCount。如果_categoryList.length10,那么我们将在ListView 中有11 项,并且索引范围将为0 - 10。所以在builder 中,我们检查index 是否等于_categoryList.length,即10。如果index等于_categoryList.length的长度,那么我们在List的末尾,我们可以简单地调用一些函数来从Api加载更多数据或显示加载小部件。

我想我猜对了你的问题,这样你就可以在用户到达列表末尾时简单地延迟加载数据,而无需使用任何第三方库。

【讨论】:

  • 我们可以使用paginable包以简单的方式做这些事情。
【解决方案2】:

这个过程称为分页。 Laravel 提供了一个函数来检查Pagination in Laravel

例如

$users = DB::table('users')->paginate(15);// 15 is limit per page

在flutter dev中也检查Paginglib。

【讨论】:

  • 我可以只使用分页插件进行分页而不对 Laravel 做任何事情
【解决方案3】:

我创建了一个示例以使用 Web 服务加载更多数据 你可以看到这个例子,你可以为你实现json数据。

https://android-pratap.blogspot.com/2018/12/flutter-infinite-listview-using.html

import 'package:akeepo/randomuser_infinitelist.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,

      ),
      home: InfiniteUsersList(),

   

    );
  }
}




import 'dart:async';
import 'dart:convert';

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

class InfiniteUsersList extends StatefulWidget {
  static String tag = 'users-page';

  @override
  State<StatefulWidget> createState() {
    return new _InfiniteUsersListState();
  }
}

class _InfiniteUsersListState extends State<InfiniteUsersList> {
  List<User> users = new List<User>();
  ScrollController _scrollController = new ScrollController();
  bool isPerformingRequest = false;
  int pageNumber = 0;

  @override
  void initState() {
    super.initState();

    // Loading initial data or first request to get the data
    _getMoreData();

    // Loading data after scroll reaches end of the list
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        _getMoreData();
      }
    });
  }

  // to show progressbar while loading data in background
  Widget _buildProgressIndicator() {
    return new Padding(
      padding: const EdgeInsets.all(8.0),
      child: new Center(
        child: new Opacity(
          opacity: isPerformingRequest ? 1.0 : 0.0,
          child: new CircularProgressIndicator(),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  // Webservice request to load 20 users data using paging
  Future<List<User>> _getUsers() async {
    List<User> users = new List<User>();
    setState(() {
      pageNumber++;
    });

    String url =
        "https://api.randomuser.me/?page=$pageNumber&results=20&seed=abc";
    print(url);

    var response = await http.get(url);
    var jsonData = json.decode(response.body);

    print(jsonData);

    var usersData = jsonData["results"];
    for (var user in usersData) {
      User newUser = User(user["name"]["first"] + user["name"]["last"],
          user["email"], user["picture"]["large"], user["phone"]);
      users.add(newUser);
    }

    return users;
  }

  _getMoreData() async {
    if (!isPerformingRequest) {
      setState(() {
        isPerformingRequest = true;
      });
      List<User> newEntries = await _getUsers(); //returns empty list
      if (newEntries.isEmpty) {
        double edge = 50.0;
        double offsetFromBottom = _scrollController.position.maxScrollExtent -
            _scrollController.position.pixels;
        if (offsetFromBottom < edge) {
          _scrollController.animateTo(
              _scrollController.offset - (edge - offsetFromBottom),
              duration: new Duration(milliseconds: 500),
              curve: Curves.easeOut);
        }
      }
      setState(() {
        users.addAll(newEntries);
        isPerformingRequest = false;
      });
    }
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text('Users',
              style:
                  TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
      body: Container(
          child: ListView.builder(
              shrinkWrap: true,
              controller: _scrollController,
              itemCount: users.length + 1,
              itemBuilder: (BuildContext context, int index) {
                if (index == users.length) {
                  return _buildProgressIndicator();
                } else {
                  return ListTile(
                    onTap: () {
                      Navigator.push(
                          context,
                          new MaterialPageRoute(
                              builder: (context) =>
                                  UserDetailPage(users[index])));
                    },
                    title: Text(users[index].fullName),
                    subtitle: Text(users[index].mobileNumber),
                    leading: CircleAvatar(
                        backgroundImage: NetworkImage(users[index].imageUrl)),
                  );
                }
              })),
    );
  }
}

class User {
  final String fullName;

  final String email;

  final String imageUrl;

  final String mobileNumber;

  User(this.fullName, this.email, this.imageUrl, this.mobileNumber);
}

// User Detail Page

class UserDetailPage extends StatelessWidget {
  final User user;

  UserDetailPage(this.user);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("User Details"),
      ),
      body: Center(
        child: Text(
          user.fullName,
          style: TextStyle(fontSize: 35.0),
        ),
      ),
    );
  }
}

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 2019-04-12
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 2017-08-23
    • 2014-03-03
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多