mirror of
https://github.com/flutter/samples.git
synced 2026-03-29 15:51:47 +00:00
Add the infinite_list sample (#440)
This PR adds a Flutter sample app that shows an implementation of the "infinite list" UX pattern. That is, a list is shown to the user as if it was continuous although it is internally paginated. This is a common feature of mobile apps, from shopping catalogs through search engines to social media clients.
This commit is contained in:
43
infinite_list/lib/src/api/fetch.dart
Normal file
43
infinite_list/lib/src/api/fetch.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'item.dart';
|
||||
import 'page.dart';
|
||||
|
||||
const catalogLength = 200;
|
||||
|
||||
/// This function emulates a REST API call. You can imagine replacing its
|
||||
/// contents with an actual network call, keeping the signature the same.
|
||||
///
|
||||
/// It will fetch a page of items from [startingIndex].
|
||||
Future<ItemPage> fetchPage(int startingIndex) async {
|
||||
// We're emulating the delay inherent to making a network call.
|
||||
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// If the [startingIndex] is beyond the bounds of the catalog, an
|
||||
// empty page will be returned.
|
||||
if (startingIndex > catalogLength) {
|
||||
return ItemPage(
|
||||
items: [],
|
||||
startingIndex: startingIndex,
|
||||
hasNext: false,
|
||||
);
|
||||
}
|
||||
|
||||
// The page of items is generated here.
|
||||
return ItemPage(
|
||||
items: List.generate(
|
||||
itemsPerPage,
|
||||
(index) => Item(
|
||||
color: Colors.primaries[index % Colors.primaries.length],
|
||||
name: 'Color #${startingIndex + index}',
|
||||
price: 50 + (index * 42) % 200,
|
||||
)),
|
||||
startingIndex: startingIndex,
|
||||
// Returns `false` if we've reached the [catalogLength].
|
||||
hasNext: startingIndex + itemsPerPage < catalogLength,
|
||||
);
|
||||
}
|
||||
23
infinite_list/lib/src/api/item.dart
Normal file
23
infinite_list/lib/src/api/item.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Item {
|
||||
final Color color;
|
||||
|
||||
final int price;
|
||||
|
||||
final String name;
|
||||
|
||||
Item({
|
||||
@required this.color,
|
||||
@required this.name,
|
||||
@required this.price,
|
||||
});
|
||||
|
||||
Item.loading() : this(color: Colors.grey, name: '...', price: 0);
|
||||
|
||||
bool get isLoading => name == '...';
|
||||
}
|
||||
24
infinite_list/lib/src/api/page.dart
Normal file
24
infinite_list/lib/src/api/page.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'item.dart';
|
||||
|
||||
const int itemsPerPage = 20;
|
||||
|
||||
class ItemPage {
|
||||
final List<Item> items;
|
||||
|
||||
final int startingIndex;
|
||||
|
||||
final bool hasNext;
|
||||
|
||||
ItemPage({
|
||||
@required this.items,
|
||||
@required this.startingIndex,
|
||||
@required this.hasNext,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user