Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit b18a4b0

Browse files
committed
MotionCompose: List loading
Change-Id: Ia7c23a9ced74070f3db860d0558d77df44dccbeb
1 parent 47e2c2d commit b18a4b0

File tree

8 files changed

+493
-2
lines changed

8 files changed

+493
-2
lines changed

MotionCompose/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ https://user-images.githubusercontent.com/1237536/142575353-8ed5cc04-34e3-45ea-9
2727
### [Layout > Fade through](app/src/main/java/com/example/android/compose/motion/demo/fadethrough)
2828

2929
https://user-images.githubusercontent.com/1237536/142538271-480a5573-4231-414a-88cd-9fd9951fc792.mp4
30+
31+
### [List > Loading](app/src/main/java/com/example/android/compose/motion/demo/loading)
32+
33+
https://user-images.githubusercontent.com/1237536/143526001-7621d2db-1228-4011-ae84-1572909e7806.mp4

MotionCompose/app/build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ dependencies {
6767
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
6868
implementation 'androidx.activity:activity-compose:1.4.0'
6969

70-
def accompanist_version = '0.21.2-beta'
70+
def accompanist_version = '0.21.3-beta'
7171
implementation "com.google.accompanist:accompanist-flowlayout:$accompanist_version"
7272
implementation "com.google.accompanist:accompanist-insets-ui:$accompanist_version"
73+
implementation "com.google.accompanist:accompanist-placeholder:$accompanist_version"
74+
75+
def lifecycle_version = '2.4.0'
76+
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
77+
78+
implementation "androidx.paging:paging-compose:1.0.0-alpha14"
7379

7480
testImplementation 'junit:junit:4.13.2'
7581
androidTestImplementation 'com.google.truth:truth:1.1.3'

MotionCompose/app/src/main/java/com/example/android/compose/motion/demo/Cheese.kt

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.example.android.compose.motion.demo
1818

19+
import androidx.annotation.DrawableRes
1920
import com.example.android.compose.motion.R
2021

2122
val CheeseImages = listOf(
@@ -25,3 +26,157 @@ val CheeseImages = listOf(
2526
R.drawable.cheese_4,
2627
R.drawable.cheese_5
2728
)
29+
30+
val CheeseNames = listOf(
31+
"Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
32+
"Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
33+
"Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
34+
"Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
35+
"Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
36+
"Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
37+
"Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
38+
"Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
39+
"Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
40+
"Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
41+
"Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
42+
"Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
43+
"Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
44+
"Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
45+
"Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
46+
"Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
47+
"Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
48+
"Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
49+
"Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
50+
"Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
51+
"Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
52+
"Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
53+
"Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
54+
"Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
55+
"Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
56+
"Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
57+
"Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
58+
"Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
59+
"Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
60+
"Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
61+
"Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
62+
"Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
63+
"Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
64+
"Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
65+
"Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
66+
"Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
67+
"Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
68+
"Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
69+
"Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
70+
"Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
71+
"Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
72+
"Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
73+
"Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
74+
"Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
75+
"Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
76+
"Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
77+
"Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
78+
"Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
79+
"Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
80+
"Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
81+
"Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
82+
"Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
83+
"Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
84+
"Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
85+
"Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
86+
"Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
87+
"Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
88+
"Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
89+
"Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
90+
"Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
91+
"Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
92+
"Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
93+
"Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
94+
"Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
95+
"Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
96+
"Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
97+
"Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
98+
"La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
99+
"Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
100+
"Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
101+
"Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
102+
"Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
103+
"Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
104+
"Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
105+
"Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
106+
"Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
107+
"Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
108+
"Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
109+
"Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
110+
"Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
111+
"Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
112+
"Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
113+
"Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
114+
"Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
115+
"Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
116+
"Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
117+
"Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
118+
"Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
119+
"Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
120+
"Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
121+
"Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
122+
"Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
123+
"Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
124+
"Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
125+
"Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
126+
"Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
127+
"Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
128+
"Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
129+
"Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
130+
"Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
131+
"Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
132+
"Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
133+
"Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
134+
"Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
135+
"Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
136+
"Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
137+
"Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
138+
"Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
139+
"Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
140+
"Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
141+
"Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
142+
"Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
143+
"Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
144+
"Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
145+
"Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
146+
"Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
147+
"Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
148+
"Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
149+
"Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
150+
"Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
151+
"Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
152+
"Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
153+
"Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
154+
"Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
155+
"Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
156+
"Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
157+
"Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
158+
"Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
159+
"Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
160+
"Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
161+
)
162+
163+
data class Cheese(
164+
val id: Long,
165+
val name: String,
166+
@DrawableRes val image: Int
167+
) {
168+
companion object {
169+
fun all(): List<Cheese> {
170+
return CheeseNames.mapIndexed { i, name ->
171+
Cheese(
172+
id = (i + 1).toLong(),
173+
name = name,
174+
image = CheeseImages[
175+
((name.hashCode() % CheeseImages.size) + CheeseImages.size)
176+
% CheeseImages.size
177+
]
178+
)
179+
}
180+
}
181+
}
182+
}

MotionCompose/app/src/main/java/com/example/android/compose/motion/demo/Demo.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package com.example.android.compose.motion.demo
1919
import androidx.compose.runtime.Composable
2020
import com.example.android.compose.motion.demo.fade.FadeDemo
2121
import com.example.android.compose.motion.demo.fadethrough.FadeThroughDemo
22+
import com.example.android.compose.motion.demo.loading.LoadingDemo
2223

2324
enum class Demo(
2425
val title: String,
@@ -51,5 +52,17 @@ enum class Demo(
5152
"AnimatedContent"
5253
),
5354
content = { FadeThroughDemo() }
55+
),
56+
57+
Loading(
58+
title = "List > Loading",
59+
description = """
60+
Motion provides timely feedback and the status of user actions. An animated placeholder
61+
UI can indicate that content is loading.
62+
""".trimIndent().replace('\n', ' '),
63+
apis = listOf(
64+
"Modifier.placeholder", "AnimationSpec"
65+
),
66+
content = { LoadingDemo() }
5467
)
5568
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (C) 2021 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.android.compose.motion.demo.loading
18+
19+
import androidx.paging.PagingSource
20+
import androidx.paging.PagingState
21+
import com.example.android.compose.motion.demo.Cheese
22+
import kotlinx.coroutines.delay
23+
24+
class CheeseDataSource : PagingSource<Int, Cheese>() {
25+
26+
override fun getRefreshKey(state: PagingState<Int, Cheese>): Int? {
27+
return state.anchorPosition
28+
}
29+
30+
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Cheese> {
31+
return params.key.let { position ->
32+
val all = Cheese.all()
33+
if (position == null) {
34+
LoadResult.Page(
35+
emptyList(),
36+
prevKey = null,
37+
nextKey = 0,
38+
itemsBefore = 0,
39+
itemsAfter = all.size
40+
)
41+
} else {
42+
// Simulate slow network.
43+
delay(3000)
44+
LoadResult.Page(
45+
all.subList(
46+
position,
47+
(position + params.loadSize).coerceAtMost(all.size)
48+
),
49+
prevKey = (position - params.loadSize).orNullIf { it < 0 },
50+
nextKey = (position + params.loadSize).orNullIf { it >= all.size },
51+
itemsBefore = position,
52+
itemsAfter = (all.size - position - params.loadSize).coerceAtLeast(0)
53+
)
54+
}
55+
}
56+
}
57+
}
58+
59+
private fun Int.orNullIf(condition: (Int) -> Boolean): Int? {
60+
return if (condition(this)) null else this
61+
}

0 commit comments

Comments
 (0)