Skip to content

Commit 1d8cfa1

Browse files
authored
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.
1 parent baa1f97 commit 1d8cfa1

File tree

73 files changed

+1947
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1947
-0
lines changed

INDEX.md

+6
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ A collection of animation examples. The app starts with basic concepts like
101101
`AnimationController` and `Tween`, then progresses to transitions and
102102
advanced demos.
103103

104+
#### [Infinite list](infinite_list) _(Flutter team)_
105+
106+
A sample implementation of the infinite list, a common UI pattern in which
107+
an arbitrarily large, paginated catalog is presented as a seamless
108+
"infinite" `ListView`.
109+
104110
## Maps
105111

106112
#### [Place tracker](place_tracker) _(Flutter team)_

MAINTENANCE.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ match any new language/SDK features, etc.).
1010
| chrome-os-best-practices | | |
1111
| experimental | | |
1212
| flutter_maps_firestore | | |
13+
| infinite_list | filiph | 5/13/20 |
1314
| isolate_example | johnpryan | 11/21/19 |
1415
| jsonexample | redbrogdon | 1/3/20 |
1516
| material_studies/shrine | | |

customer_testing

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ cd "flutter_maps_firestore"
99
flutter test
1010
cd ..
1111

12+
cd "infinite_list"
13+
flutter test
14+
cd ..
15+
1216
cd "isolate_example"
1317
flutter test
1418
cd ..

customer_testing.bat

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ cd "flutter_maps_firestore"
66
flutter test || exit 1
77
cd ..
88

9+
cd "infinite_list"
10+
flutter test || exit 1
11+
cd ..
12+
913
cd "isolate_example"
1014
flutter test || exit 1
1115
cd ..

infinite_list/.gitignore

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
12+
# IntelliJ related
13+
*.iml
14+
*.ipr
15+
*.iws
16+
.idea/
17+
18+
# The .vscode folder contains launch configuration and tasks you configure in
19+
# VS Code which you may wish to be included in version control, so this line
20+
# is commented out by default.
21+
.vscode/
22+
23+
# Flutter/Dart/Pub related
24+
**/doc/api/
25+
.dart_tool/
26+
.flutter-plugins
27+
.packages
28+
.pub-cache/
29+
.pub/
30+
/build/
31+
32+
# Android related
33+
**/android/**/gradle-wrapper.jar
34+
**/android/.gradle
35+
**/android/captures/
36+
**/android/gradlew
37+
**/android/gradlew.bat
38+
**/android/local.properties
39+
**/android/**/GeneratedPluginRegistrant.java
40+
41+
# iOS/XCode related
42+
**/ios/**/*.mode1v3
43+
**/ios/**/*.mode2v3
44+
**/ios/**/*.moved-aside
45+
**/ios/**/*.pbxuser
46+
**/ios/**/*.perspectivev3
47+
**/ios/**/*sync/
48+
**/ios/**/.sconsign.dblite
49+
**/ios/**/.tags*
50+
**/ios/**/.vagrant/
51+
**/ios/**/DerivedData/
52+
**/ios/**/Icon?
53+
**/ios/**/Pods/
54+
**/ios/**/.symlinks/
55+
**/ios/**/profile
56+
**/ios/**/xcuserdata
57+
**/ios/.generated/
58+
**/ios/Flutter/App.framework
59+
**/ios/Flutter/Flutter.framework
60+
**/ios/Flutter/Generated.xcconfig
61+
**/ios/Flutter/app.flx
62+
**/ios/Flutter/app.zip
63+
**/ios/Flutter/flutter_assets/
64+
**/ios/Flutter/flutter_export_environment.sh
65+
**/ios/ServiceDefinitions.json
66+
**/ios/Runner/GeneratedPluginRegistrant.*
67+
68+
# Exceptions to above rules.
69+
!**/ios/**/default.mode1v3
70+
!**/ios/**/default.mode2v3
71+
!**/ios/**/default.pbxuser
72+
!**/ios/**/default.perspectivev3
73+
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

infinite_list/README.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# infinite_list
2+
3+
A Flutter sample app that shows an implementation of the "infinite list" UX pattern. That is,
4+
a list is shown to the user as if it was continuous although it is internally paginated.
5+
This is a common feature of mobile apps, from shopping catalogs through search engines
6+
to social media clients.
7+
8+
![An animated gif of the app in action](https://user-images.githubusercontent.com/919717/81858860-3a1e3280-9519-11ea-8e9c-9d22ac1bf0ed.gif)
9+
10+
This particular sample uses the [Provider][] package but any other state management approach
11+
would do.
12+
13+
[Provider]: https://pub.dev/packages/provider
14+
15+
## Goals for this sample
16+
17+
* Show how UI code can be "shielded" from complex asynchrony and pagination logic using
18+
a `ChangeNotifier`.
19+
* Illustrate use of `Selector` from the Provider package.
20+
21+
## Questions/issues
22+
23+
If you have a general question about Flutter, the best places to go are:
24+
25+
* [Flutter documentation](https://flutter.dev/)
26+
* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter)
27+
28+
If you run into an issue with the sample itself, please
29+
[file an issue](https://github.com/flutter/samples/issues).

infinite_list/analysis_options.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
include: package:pedantic/analysis_options.yaml
2+
3+
analyzer:
4+
strong-mode:
5+
implicit-casts: false
6+
implicit-dynamic: false
7+
8+
linter:
9+
rules:
10+
- avoid_types_on_closure_parameters
11+
- avoid_void_async
12+
- await_only_futures
13+
- camel_case_types
14+
- cancel_subscriptions
15+
- close_sinks
16+
- constant_identifier_names
17+
- control_flow_in_finally
18+
- directives_ordering
19+
- empty_statements
20+
- hash_and_equals
21+
- implementation_imports
22+
- non_constant_identifier_names
23+
- package_api_docs
24+
- package_names
25+
- package_prefixed_library_names
26+
- test_types_in_equals
27+
- throw_in_finally
28+
- unnecessary_brace_in_string_interps
29+
- unnecessary_getters_setters
30+
- unnecessary_new
31+
- unnecessary_statements

infinite_list/android/.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
gradle-wrapper.jar
2+
/.gradle
3+
/captures/
4+
/gradlew
5+
/gradlew.bat
6+
/local.properties
7+
GeneratedPluginRegistrant.java
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
def localProperties = new Properties()
2+
def localPropertiesFile = rootProject.file('local.properties')
3+
if (localPropertiesFile.exists()) {
4+
localPropertiesFile.withReader('UTF-8') { reader ->
5+
localProperties.load(reader)
6+
}
7+
}
8+
9+
def flutterRoot = localProperties.getProperty('flutter.sdk')
10+
if (flutterRoot == null) {
11+
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12+
}
13+
14+
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15+
if (flutterVersionCode == null) {
16+
flutterVersionCode = '1'
17+
}
18+
19+
def flutterVersionName = localProperties.getProperty('flutter.versionName')
20+
if (flutterVersionName == null) {
21+
flutterVersionName = '1.0'
22+
}
23+
24+
apply plugin: 'com.android.application'
25+
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26+
27+
android {
28+
compileSdkVersion 28
29+
30+
lintOptions {
31+
disable 'InvalidPackage'
32+
}
33+
34+
defaultConfig {
35+
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36+
applicationId "dev.flutter.infinitelist"
37+
minSdkVersion 16
38+
targetSdkVersion 28
39+
versionCode flutterVersionCode.toInteger()
40+
versionName flutterVersionName
41+
}
42+
43+
buildTypes {
44+
release {
45+
// TODO: Add your own signing config for the release build.
46+
// Signing with the debug keys for now, so `flutter run --release` works.
47+
signingConfig signingConfigs.debug
48+
}
49+
}
50+
}
51+
52+
flutter {
53+
source '../..'
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="dev.flutter.infinitelist">
3+
<!-- Flutter needs it to communicate with the running application
4+
to allow setting breakpoints, to provide hot reload, etc.
5+
-->
6+
<uses-permission android:name="android.permission.INTERNET"/>
7+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="dev.flutter.infinitelist">
3+
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
4+
calls FlutterMain.startInitialization(this); in its onCreate method.
5+
In most cases you can leave this as-is, but you if you want to provide
6+
additional functionality it is fine to subclass or reimplement
7+
FlutterApplication and put your custom class here. -->
8+
<application
9+
android:name="io.flutter.app.FlutterApplication"
10+
android:label="infinitelist"
11+
android:icon="@mipmap/ic_launcher">
12+
<activity
13+
android:name=".MainActivity"
14+
android:launchMode="singleTop"
15+
android:theme="@style/LaunchTheme"
16+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
17+
android:hardwareAccelerated="true"
18+
android:windowSoftInputMode="adjustResize">
19+
<!-- Specifies an Android theme to apply to this Activity as soon as
20+
the Android process has started. This theme is visible to the user
21+
while the Flutter UI initializes. After that, this theme continues
22+
to determine the Window background behind the Flutter UI. -->
23+
<meta-data
24+
android:name="io.flutter.embedding.android.NormalTheme"
25+
android:resource="@style/NormalTheme"
26+
/>
27+
<!-- Displays an Android View that continues showing the launch screen
28+
Drawable until Flutter paints its first frame, then this splash
29+
screen fades out. A splash screen is useful to avoid any visual
30+
gap between the end of Android's launch screen and the painting of
31+
Flutter's first frame. -->
32+
<meta-data
33+
android:name="io.flutter.embedding.android.SplashScreenDrawable"
34+
android:resource="@drawable/launch_background"
35+
/>
36+
<intent-filter>
37+
<action android:name="android.intent.action.MAIN"/>
38+
<category android:name="android.intent.category.LAUNCHER"/>
39+
</intent-filter>
40+
</activity>
41+
<!-- Don't delete the meta-data below.
42+
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
43+
<meta-data
44+
android:name="flutterEmbedding"
45+
android:value="2" />
46+
</application>
47+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dev.flutter.infinitelist;
2+
3+
import io.flutter.embedding.android.FlutterActivity;
4+
5+
public class MainActivity extends FlutterActivity {
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Modify this file to customize your launch splash screen -->
3+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4+
<item android:drawable="@android:color/white" />
5+
6+
<!-- You can insert your own image assets here -->
7+
<!-- <item>
8+
<bitmap
9+
android:gravity="center"
10+
android:src="@mipmap/launch_image" />
11+
</item> -->
12+
</layer-list>
Loading
Loading
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<!-- Theme applied to the Android Window while the process is starting -->
4+
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
5+
<!-- Show a splash screen on the activity. Automatically removed when
6+
Flutter draws its first frame -->
7+
<item name="android:windowBackground">@drawable/launch_background</item>
8+
</style>
9+
<!-- Theme applied to the Android Window as soon as the process has started.
10+
This theme determines the color of the Android Window while your
11+
Flutter UI initializes, as well as behind your Flutter UI while its
12+
running.
13+
14+
This Theme is only used starting with V2 of Flutter's Android embedding. -->
15+
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
16+
<item name="android:windowBackground">@android:color/white</item>
17+
</style>
18+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="dev.flutter.infinitelist">
3+
<!-- Flutter needs it to communicate with the running application
4+
to allow setting breakpoints, to provide hot reload, etc.
5+
-->
6+
<uses-permission android:name="android.permission.INTERNET"/>
7+
</manifest>

infinite_list/android/build.gradle

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
buildscript {
2+
repositories {
3+
google()
4+
jcenter()
5+
}
6+
7+
dependencies {
8+
classpath 'com.android.tools.build:gradle:3.5.0'
9+
}
10+
}
11+
12+
allprojects {
13+
repositories {
14+
google()
15+
jcenter()
16+
}
17+
}
18+
19+
rootProject.buildDir = '../build'
20+
subprojects {
21+
project.buildDir = "${rootProject.buildDir}/${project.name}"
22+
}
23+
subprojects {
24+
project.evaluationDependsOn(':app')
25+
}
26+
27+
task clean(type: Delete) {
28+
delete rootProject.buildDir
29+
}
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
org.gradle.jvmargs=-Xmx1536M
2+
android.enableR8=true
3+
android.useAndroidX=true
4+
android.enableJetifier=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Fri Jun 23 08:50:38 CEST 2017
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

0 commit comments

Comments
 (0)