Loading...
Home
  • Tech Blogs
  • Videos
  • Conferences
    • Droidcon News
    • Upcoming Conferences
    • Become a Partner
    • Past Events
    • Keep Me Informed
    • Diversity Scholarships
  • Community
    • droidcon Team
    • How to Hold a Droidcon
  • Android Careers
Sign In

Global CSS

 

Fully cross-platform Kotlin applications (almost)

 

 
Arkadii Ivanov
Android Engineer @ Badoo
Published: December 02, 2020
Tweet
Share
 

 

In my last article “Decompose — experiments with Kotlin Multiplatform lifecycle-aware components and navigation”, I mentioned two cases when we can’t share code using Kotlin Multiplatform. The first one was navigation and the second one was UI. In that article we managed to share the navigation logic using the Decompose library. But UI was still platform specific.

Good news! Recently JetBrains released its multiplatform implementation of Jetpack Compose, and it is now possible to have a shared UI. Basically, the multiplatform Compose can now be used on both Android and JVM. And the latter works on Linux, macOS and Windows.

Since both navigation and UI can now be shared, we can create almost cross-platform applications. Why almost? Because some parts may still require platform-specific API. And this is actually a big benefit, you choose what to share.

 

(De)Compose

How can we use both libraries so that we have a completely shared code, including navigation and UI? Let’s create a very simple Todo list application. There will be just two screens: List and Details.

 

Image for post

 

If you’ve read the introductory article on Decompose, you probably know its concept of components. If not, I recommend that you read it first. In this example every screen will be a component. And there will be a Root component for navigation between screens.

We will need a common interface for all three components:

 

 

So components can now be rendered.

 

The List screen

Let’s start with the List screen. We can first make the UI, and then integrate it into the component with business logic. Thanks to JetBrains Compose we can put all this code in the commonMain source set, which means it is multiplatform!

The bottom input field with the “plus” button can be implemented like this:

 

 

Here is the list item:

 

 

And the whole List screen using the above functions:

 

 

Now it’s time for TodoList component:

 

 

We created a class and used DI to provide all required dependencies.

The ListState data class contains all the data required for the screen. The state is managed by Compose MutableState, which is created using the mutableListOf function. You can learn more about Compose state in the codelab.

The render function will be called automatically whenever the MutableState value changes.

 

The Details screen

This will be a very simple screen. No mutable state is required, just display the data. And as before, we will pass all dependencies and data via constructor.

 

 

The Root component

Now we have components for both screens: TodoList and TodoDetails. Time to add navigation! The TodoRoot will integrate both children and navigate between them.

 

 

Decompose provides the Router, which makes navigation a very simple task. Each child component is created using Parcelable configuration. In this case we defined the Config sealed class with just two entries: List and Details. The Parcelize extension comes to the rescue in implementing Parcelable interface.

Such an approach brings two benefits:

  • It allows the navigation back stack to be preserved in Android when Activity or process is recreated.
  • It enables proper DI and IoC when instantiating child components (unlike the AndroidX FragmentFactory).

The render function just renders the currently active child. The children {} extension function listens for back stack changes and takes care of UI state preservation.

Now we have everything ready, it’s time to integrate the TodoRoot component into both Android and Desktop applications. So far, all our code has been fully multiplatform. The following integration parts will be the only platform-specific code. We will use some handy extensions from Decompose to make the integration easier.

 

Android application

 

 

Desktop application

 

 

Preserving the list state

Currently if we rotate the list screen on Android, all data will be lost. Let’s fix this and preserve the state. We’ll use the StateKeeper from Decompose.

 

 

So if there is a saved state, it is used as the initial state. Otherwise an empty state is created.

In addition, the List UI state is now fully preserved even if the Details screen is rotated.

 

Image for post

 

Advanced example

If you are interested in a more advanced example, checkout the Todo example in the JetBrains Compose repository.

Its highlights:

  • Most of the code is shared: data, business logic, presentation, navigation and UI
  • View state is preserved when navigating between screens, Android configuration change, etc.
  • Dependency injection
  • Model-View-Intent (aka MVI) architectural pattern
  • Persistent storage using SQLDelight
  • Multi-module tree structure
  • Unit and integration tests

 

Conclusion

When used together, Decompose and JetBrains Compose libraries allow us to share most of the code, including navigation and UI. Currently JetBrains Compose supports only Android and Desktop JVM. But there is no doubt, more platforms will be supported in future. Each such addition will add more power to the stack.

Decompose is a multiplatform library. At the moment the following targets are supported: Android, JVM, iOS and JavaScript. So we can share Compose UI between Android and Desktop targets, and plug in platform-specific UI (like SwiftUI or React) for other targets.

Decompose takes care of navigation and state preservation. This improves the UX when moving between screens.

Thank you for reading the article, and don’t forget to follow me on Twitter!

 

 

 

Tags: Multiplatform, Kotlin, Jetpack Compose, Navigation, Cross Platform

 

View original article at: 


 

Originally published: November 16, 2020

Android News
Compose CameraX on Android
Compose CameraX on Android

By Peng Jiang

Android new UI toolkit Jetpack compose is in beta now, which has all the features you need to build production-ready apps. CameraX is another Jetpack support library, which let you control the camera easier. As compose is still under development, lots of the views are still not available the compose way.

By ProAndroidDev -
Android News
Getting… your BottomSheetScaffold working on Jetpack Compose Beta 03
Getting… your BottomSheetScaffold working on Jetpack Compose Beta 03

By Carlos Mota

It’s Monday, no releases this week, and… there’s a new version of Jetpack Compose — beta 03—available. What a perfect time to just increment 02 to 03 and see what’s new. The API is (almost) final so after updating from alpha to beta there weren’t any big changes to do. However, and remember that’s still in development, there’s always something that I need to update. 

By ProAndroidDev -
Android News
Noisy Code With Kotlin Scopes
Noisy Code With Kotlin Scopes

By Chetan Gupta

Scopes make your code more readable? think again... You are going to encounter these scope functions namely let, run, apply, also, within every Kotlin codebase, along with all the mischievous ways developers exploit their usage from the way they were intended for. Let see how popular opinion on those ends up just as a code noise.

By ProAndroidDev -
Android News
Improving Android DataBinding with Bindables library
Improving Android DataBinding with Bindables library

By Jaewoong Eum

DataBinding is one of the most important factors for MVVM architecture. The basic concept of DataBinding is to link the view and view model via observer patterns, properties, event callbacks, etc. Linking and automating communication between the view via the bound properties or something in the view model has a lot of benefits in the MVVM architecture concept.

By ProAndroidDev -
droidcon News

Tech Showcases,

Developer Resources &

Partners

/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/home-details/EmployerBrandingHeader
EmployerBrandingHeader
https://jobs.droidcon.com/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/jobs-droidcon/jobs.droidcon.com
jobs.droidcon.com

Latest Android Jobs

http://www.kotlinweekly.net/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/kotlin-weekly/Kotlin Weekly
Kotlin Weekly

Your weekly dose of Kotlin

https://proandroiddev.com/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/pad/ProAndroidDev
ProAndroidDev

Android Tech Blogs, Case Studies and Step-by-Step Coding

/detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando
Zalando

Meet one of Berlin's top employers

/detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success
Academy for App Success

Google Play resources tailored for the global droidcon community

Follow us

Team droidcon

Get in touch with us

Write us an Email

 

 

Quicklinks

> Code of Conduct

> Terms and Conditions

> How to hold a conference

> FAQs

> Imprint

Droidcon is a registered trademark of Mobile Seasons GmbH Copyright © 2020. All rights reserved.

powered by Breakpoint One