Lesson 01 Compose GUI ‐ Simple List - FranGarc/LearningPath GitHub Wiki
Topic: Compose GUI - Simple List.
Jetpack Compose Android’s modern toolkit for building native UI. It makes building Android UI faster and easier.
Compose uses a declarative API, which means that all you need to do is describe your UI - Compose takes care of the rest.
With Compose, you build small, stateless components that are not tied to a specific activity or fragment. That makes them easy to reuse and test.
In Compose, state is explicit and passed to the composable. That way there’s one single source of truth for the state, making it encapsulated and decoupled. Then, as app state changes, your UI automatically updates.
Task: Simple list.
Create a screen that displays a list of elements. Each element will contain a pokemon's name and its image (sprite). There's mock data in Additional resources section for it.
Example GUI
This is a mere example, don't let it limit your design.
Requisites
- The list will have a 5dp padding in each side.
- The elements:
- will be 120dp high and occupy the whole width.
- will contain a text and a remote image. The image will be aligned to one extrem of the element, the text will be centred vertically, next to the image with 10dp padding to separate both.
- Use different icons for placeholder (what the app will show as an image is still loading) and for error (what the app shows when the image from the URL couldn't be loaded for some reason)
Tips & Advice.
- Hardcode the data in Additional resources to feed the list in a separate class called DataSource to keep the Activity code a bit cleaner. Just code everything else into the Activity class. We'll be refactoring in future lessons.
- A list in Compose is made from a LazyColumn (list container) and a Row (element container). Research how to feed the data from DataSource into the LazyColumn.
- Remote Image
- Since the images we're using are stored remotely, we'll need to use a way to load them remotely. Research Coil for that.
- Get two different icons (svg are the best scalling for different screens). Use one of them as a placeholder while the image is loading, and the other for the error image - the one that shows up when there was an issue loading up the remote image.
Research terms.
- Composable
- LazyColumn
- Row
- AsyncImage / Coil /ImageRequest
- Text
- Log class
Dependencies
- implementation("io.coil-kt:coil-compose:2.2.2")
Additional resources.
Use the following Json to create the list of elements. The Android Studio plugin Json to Kotlin Class will help you creating the data class structure, but you'll need to hardocde the values manually.
{ [ { "name": "bulbasaur", "url": "https://pokeapi.co/api/v2/pokemon/1/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png" }, { "name": "ivysaur", "url": "https://pokeapi.co/api/v2/pokemon/2/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/2.png" }, { "name": "venusaur", "url": "https://pokeapi.co/api/v2/pokemon/3/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/3.png" }, { "name": "charmander", "url": "https://pokeapi.co/api/v2/pokemon/4/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png" }, { "name": "charmeleon", "url": "https://pokeapi.co/api/v2/pokemon/5/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/5.png" }, { "name": "charizard", "url": "https://pokeapi.co/api/v2/pokemon/6/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/6.png" }, { "name": "squirtle", "url": "https://pokeapi.co/api/v2/pokemon/7/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png" }, { "name": "wartortle", "url": "https://pokeapi.co/api/v2/pokemon/8/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/8.png" }, { "name": "blastoise", "url": "https://pokeapi.co/api/v2/pokemon/9/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/9.png" }, { "name": "caterpie", "url": "https://pokeapi.co/api/v2/pokemon/10/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/10.png" }, { "name": "metapod", "url": "https://pokeapi.co/api/v2/pokemon/11/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/11.png" }, { "name": "butterfree", "url": "https://pokeapi.co/api/v2/pokemon/12/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/12.png" }, { "name": "weedle", "url": "https://pokeapi.co/api/v2/pokemon/13/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/13.png" }, { "name": "kakuna", "url": "https://pokeapi.co/api/v2/pokemon/14/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/14.png" }, { "name": "beedrill", "url": "https://pokeapi.co/api/v2/pokemon/15/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/15.png" }, { "name": "pidgey", "url": "https://pokeapi.co/api/v2/pokemon/16/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/16.png" }, { "name": "pidgeotto", "url": "https://pokeapi.co/api/v2/pokemon/17/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/17.png" }, { "name": "pidgeot", "url": "https://pokeapi.co/api/v2/pokemon/18/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/18.png" }, { "name": "rattata", "url": "https://pokeapi.co/api/v2/pokemon/19/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/19.png" }, { "name": "raticate", "url": "https://pokeapi.co/api/v2/pokemon/20/", "defaultSprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/20.png" } ] }