How I built this nice looking app using Jetpack Compose

Inuwa Ibrahim
6 min readJul 6, 2022

Jetpack compose is the future of building UI’s on Android.

If you are completely new to android and don’t know what Jetpack Compose is — It’s basically a new way of building native user interfaces. Read more here

In this article, you would learn about UI development with Jetpack Compose following best practices.

What We Are Building

We’ll build an app that shows a list of albums from apple music. Let’s call the app MyMusic.

From my github repository, you would learn how to:

1. Build a splash screen using recommended approach (splash API)
2. Use various UI composables such as Rows, Columns, Lazy Columns, Animations API’s
3. Use MVVM pattern with Jetpack Compose (Using observables and state holders like StateFlow)
4. Use Room Database to persist local data from a JSON file
5. Implement Search Feature on an app
6. Implement simple navigation with transition animation using this great library
7. How to efficiently display images like gifs etc using this awesome library

To reduce complexities, this article focuses on UI.

FullCode

Click here to get the full code from my Github. You can also download the latest APK from the repo in the download section to test the app. PR’s are always welcome :)

Prerequisite

  • I’ll assume you have basic knowledge of developing android apps
  • You have added the dependencies needed. Check my github repository for that
  • You understand Compose basic Theming. Read More here (Also check the app/ui/theme package)

Splash Screen

The splash screen is what shows just before the content of your app loads. It’s a way to show users your brand image or logo.

fig 1.

Sadly, there is no way to implement the current splash API exclusively with compose. We still need some xml’s :(

  • Under values/themes.xml. Add your splash screen theme

The comments explains what each attribute does.

Make sure you include the theme in your AndroidManifest.xml root <application tag

android:theme="@style/Theme.MyMusic.SplashScreen"
  • Install the theme in your Launcher Activity, which should be your MainActivity.kt
class MainActivity : ComponentActivity()
.........
super.onCreate(savedInstanceState)
......
installSplashScreen()
  • Run the app and your splash screen should work.

Start Screen

fig 2.
  • Create a new composable, name that StartScreen (Check ui/screens/start/StartScreen.kt)

@RootNavGraph — This is an annotation from our navigation library indicating that this is the start screen of our nav graph.

@Destination — Also from our navigation library indicating that this composable is a destination which a user can navigate to and fro from. We also included a style attribute for transition animation (Check animations/StartScreenTransition.kt)

@Modifier — A parameter passed to the composable to decorate the composable (e.g sizes, background etc)

@Navigator — Helps us move from one destination or screen to another

  • As you can see from fig 2. above, the card is placed on top of kanye west image. As such, we would make use of a Box
  • A Box is a UI composable that lets you place items on top of other items.
  • Place the following composable between the { .. } above
Box(
modifier = modifier
.fillMaxSize()
){
.......}
  • The modifier indicates that the box should fill the size of the entire screen
  • Now, inside the box, we place our kanye image, which is a gif (Using our image loading library)
Box(
modifier = modifier
.fillMaxSize()
){

GlideImage(
imageModel = R.drawable.kanye
)
........
}
  • After that, we need to create our card which will be placed on top of the kanye image. We can use Card composable for that.
  • We indicated that the card should fill exactly 80% of the screen in width, aligned to the bottom centre with a 50dp padding.
  • Also, we indicated that we wanted a rounded corner card with a radius of 50dp with a secondary background color — Self explanatory 👍
  • From fig 2 above, the red arrow indicates items arranged from top to bottom (vertically)
fig a
  • For that kind of vertical arrangement, we’ll make use of a composable called Column
  • The modifiers and attributes are self explanatory.
  • We are making sure that all items placed in this column are spaced evenly from top to bottom (vertically)
  • Also, making sure that the items are centred from left to right (horizontally)
  • We’ll now add the rest of our UI composables inside the column — Text and Button.
  • The full code for start screen is below:
  • Notice how on click of our Button, we navigate to the HomeScreenDestination using onClick lambda parameter.
  • Make sure you have created the HomeScreen composable, check ui/screens/home/HomeScreen for that. It should be annotated with @Destination. This would create the HomeScreenDestination file automatically for you after a successful build.

Home Screen

fig 3.
  • You must have created the HomeScreen composable (Check ui/screens/home/HomeScreen.kt)
  • The home screen basically consist of items arranged from top to bottom — Vertically (as shown in the dark arrow above)
@Destination(style = StartScreenTransitionAnimation::class)
@Composable
fun HomeScreen(
navigator: DestinationsNavigator,
albumDatabaseViewModel: AlbumDatabaseViewModel = hiltViewModel()
){
//--> Home screen layout here}
  • Personally, I love clean and reusable codes. So, I wouldn’t place the entire home screen items in this composable. We’ll create another composable named HomeScreenItems.kt and place it inside our homeScreen

This is our HomeScreenItems.kt file

  • This composable takes in lots of parameters. I would highlight the ones I haven’t explained before

albums — A list of albums from room database entity/table

albumDatabaseViewModel — A viewModel for our datasource

onCardClicked — Lambda function called when a card is clicked

onPopularAlbumClicked — Lambda function called when a popular album is clicked

  • Since we want our home screen to be scrollable and items loaded gradually as we scroll, we’ll make use of LazyColumn as the root layout
  • LazyColumn is a vertical scrolling composable list that only composes and lays out the currently visible items.
  • So, what do we want to place inside the LazyColumn? Non-dynamic content (Single static item) and Dynamic content (Items that changes).
  • From fig.3, you would observe that the items in the blue box and green boxes are non-dynamic content. They don’t change.
  • So, we would use a single item lambda function to display those item(s).
  • A composable for each sections — UserHomeSection(), SearchSection() and PopularAlbumSection()
  • This is done for separation of concern and mostly reusability (For example, I can make use of the SearchSection composable somewhere else in the app without duplicating the whole codes inside the SearchSection composable) — In-fact, I used the same composable for SearchScreen
  • Notice how in fig.3, the first box is marked with blue. This is just to indicate that the items are placed from Left-Right (Horizontally). So we need to make use of a composable called Row for that.
  • A Row is used to place items horizontally on the screen
  • Now, for the dynamic items which we obtain from room database, we would use a lambda function called items to display that.
  • Our full HomeScreenItems.kt becomes:
  • I created a reusable composable called AlbumCard which we can use as a model to display all the dynamic items.
  • Make sure you check full code to properly understand how things work.

I hope I have been able to explain how basic UI works with Jetpack Compose. For more information on UI’s with compose check out the official documentation

I would love to cover everything about this app, NON-UI related but that would make this post extremely lengthy.

Check full code and let me know if you need any assistance:

CONTACT ME
https://linktr.ee/Ibrajix

--

--