compose-multiplatform
This is a dependency for Jetpack Compose's multi-platform features.
Currently supported platforms: Android, iOS, Desktop (JVM).
Notice
This module is still under development and testing, and the API may change before the 1.0.0
version is officially released.
We are welcome you to make suggestions to us at GitHub Issues.
Configure Dependency
You can add this module to your project using the following method.
This is a Kotlin Multiplatform dependency, you need the org.jetbrains.kotlin.multiplatform
plugin to apply the relevant dependencies.
SweetDependency (Recommended)
Add dependencies to your project SweetDependency
configuration file.
libraries:
com.highcapable.betterandroid:
# commonMain
compose-multiplatform:
version: +
# androidMain
compose-multiplatform-android:
version-ref: <this>::compose-multiplatform
# iosArm64Main
compose-multiplatform-iosarm64:
version-ref: <this>::compose-multiplatform
# iosX64Main
compose-multiplatform-iosx64:
version-ref: <this>::compose-multiplatform
# iosSimulatorArm64Main
compose-multiplatform-iossimulatorarm64:
version-ref: <this>::compose-multiplatform
# desktopMain
compose-multiplatform-desktop:
version-ref: <this>::compose-multiplatform
Configure dependencies in your project build.gradle.kts
.
If you use multi-platform dependencies in a regular project, you only need to deploy the corresponding platform suffix dependencies as needed.
implementation(com.highcapable.betterandroid.compose.multiplatform.android)
implementation(com.highcapable.betterandroid.compose.multiplatform.iosarm64)
implementation(com.highcapable.betterandroid.compose.multiplatform.iosx64)
implementation(com.highcapable.betterandroid.compose.multiplatform.iossimulatorarm64)
implementation(com.highcapable.betterandroid.compose.multiplatform.desktop)
If you use multi-platform dependencies in a multi-platform project, you need to add the compose-multiplatform
dependency in commonMain
.
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation(com.highcapable.betterandroid.compose.extension)
}
}
}
}
Traditional Method
Configure dependencies in your project build.gradle.kts
.
If you use multi-platform dependencies in a regular project, you only need to deploy the corresponding platform suffix dependencies as needed.
implementation("com.highcapable.betterandroid:compose-multiplatform-android:<version>")
implementation("com.highcapable.betterandroid:compose-multiplatform-iosarm64:<version>")
implementation("com.highcapable.betterandroid:compose-multiplatform-iosx64:<version>")
implementation("com.highcapable.betterandroid:compose-multiplatform-iossimulatorarm64:<version>")
implementation("com.highcapable.betterandroid:compose-multiplatform-desktop:<version>")
If you use multi-platform dependencies in a multi-platform project, you need to add the compose-multiplatform
dependency in commonMain
.
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("com.highcapable.betterandroid:compose-multiplatform:<version>")
}
}
}
}
Please change <version>
to the version displayed at the top of this document.
Function Introduction
You can view the KDoc click here.
In order to allow developers who are adapted to native Android development to adapt to various platforms faster, BetterAndroid
seamlessly provides multi-platform support with the help of the cross-platform features of Kotlin Multiplatform and Jetpack Compose.
The following are the functions currently being developed and completed.
We welcome more developers to participate in the development, if possible, you are welcome to submit a PR to contribute to this project or make suggestions to us through GitHub Issues.
Features marked with "✅" indicate available, "❎" indicates not supported by the platform, "🚧" indicates preparation or under development (WIP), and "🔨" indicates planned development.
Feature Name | Description | Android | iOS | Desktop |
---|---|---|---|---|
BackHandler | System back pressed event for Android. | ✅ | ❎ | ❎ |
PlatformWindowInsets | Window insets for mobile platforms. | 🚧 | 🚧 | ❎ |
PlatformNotificationManager | Notifications post & management to the system. | 🔨 | 🔨 | 🔨 |
PlatformSystemBarsController | System bar-related controller for mobile platforms. | ✅ | ✅ | ❎ |
PlatformDisplayController | Screen rotation & brightness controller for mobile platforms. | 🚧 | 🚧 | ❎ |
PlatformHwSensorController | Hardware sensors (such as vibration) for mobile platforms. | 🔨 | 🔨 | ❎ |
The features that have been developed will be described in detail below.
Initial Configuration
Contents of This Section
iosMain
Basic component UIViewController
.
UIViewController → AppComponentUIViewController
Extensions for UIViewController
to creating a starting point for Compose.
Before starting, we recommend that you configure your project structure as follows.
Tips
We recommend and refer to Quick Start → Project Template to create a project without manual configuration.
You can also use the Kotlin Multiplatform Wizard to automatically help you complete the Gradle script compilation configuration of the iOS project.
General Section
Please create an App.kt
in commonMain
which will serve as the starting point for Compose.
The following example
@Composable
fun App() {
// Your composables content here.
}
Android Platform
First, please import the ui-component module in the corresponding Android project.
Then, please refer to ui-component → Activity to use AppComponentActivty
as the starting point for Compose.
The following example
class MainActivity : AppComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
App()
}
}
}
iOS Platform
Notice
You need to have a computer or virtual machine that can run macOS and have the Xcode environment configured correctly.
First, you need to manually create an iOS App Xcode project, select Swift as the language, and select Storyboard
in the Interface
column.
Then, create an AppComponentUIViewController
in the MainViewController.kt
file in iosMain
using the following method.
The following example
fun createMainViewController() = AppComponentUIViewController {
App()
}
Then, determine the shared module name you set in build.gradle.kts
for your iOS project.
The following example
kotlin {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
// Set the shared module name.
baseName = "ComposeApp"
// It is recommended to set it as a static library.
isStatic = true
}
}
}
Next, make the following configurations to the AppDelegate.swift
file in your iOS project.
If your iOS project was created using Swift UI, please create this file manually and remove the SwiftApp.swift
related files created using Swift UI.
The following example
import UIKit
import ComposeApp // Here is your shared module name.
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Create a new UIWindow.
window = UIWindow(frame: UIScreen.main.bounds)
// Set the controller of the root view.
// MainViewControllerKt is the automatically generated Kotlin code in ComposeApp.h.
window?.rootViewController = MainViewControllerKt.createMainViewController()
// Make it visible.
window?.makeKeyAndVisible()
return true
}
}
Notice
Do not use UIViewControllerRepresentable
to create UIViewController
for Swift UI, although this is currently the code that the Kotlin Multiplatform Wizard automatically generates for you.
But this will cause the related functions of System Bars (Status Bars, Navigation Bars, Home Indicator, etc) to fail, because Swift UI will take over the state of the entire view, at this time, you can only control system bars in Swift UI.
Desktop Platform
Please use the following method to create the starting point of Compose in the corresponding Java project Main.kt
.
The following example
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
// Set window title.
title = "My App",
// Set window size.
state = rememberWindowState(width = 300.dp, height = 500.dp)
) {
App()
}
}
System Event
Contents of This Section
commonMain
Extensions for system back pressed event.
Although androidx.activity:activity-compose
provides BackHandler
, it can only be used in Android.
BetterAndroid
provides multi-platform distribution support for BackHandler
, you can use it directly in commonMain
, but it will only take effect on the Android platform.
BackHandler
is implemented in Android using BackPressedController
in ui-component → System Event, you can refer to ui-component → Activity to use AppComponentActivty
or manually implement the IBackPressedController
interface for your Activity
.
Below is a usage example that is identical to the BackHandler
usage provided in androidx.activity:activity-compose
.
The following example
// Create enabled state.
var enabled by remember { mutableStateOf(true) }
// Create BackHandler.
BackHandler(enabled) {
// Handle back pressed event.
}
System Bars (Status Bars, Navigation Bars, Home Indicator, etc)
Contents of This Section
commonMain
System bars controller for Android and iOS.
Native system bars controller corresponding to Android and iOS.
System bars style.
System bars type.
System bars behavior.
SystemBars → rememberSystemBarsController
Extensions for system bars.
iosMain
System bars controller.
System bars style.
System bars type.
System bars behavior.
In both Android and iOS, you need to control and adjust the status bars and navigation bars (home indicator) provided by the system to give users a better experience.
For this purpose, BetterAndroid
provides you with PlatformSystemBarsController
, which can easily control the system bars of each platform through a common API.
The working principle of PlatformSystemBarsController
is to distribute it to the corresponding native controller according to different platforms through NativeSystemBarsController
.
Before starting to use it, make sure you have read Initial Configuration and completed the relevant configuration for the current project.
PlatformSystemBarsController
uses SystemBarsController
in ui-component → System bars (Status bars, Navigation bars, etc) in Android accomplish, you can refer to ui-component → Activity to use AppComponentActivty
or manually implement the ISystemBarsController
interface for your Activity
.
You can get the PlatformSystemBarsController
object globally in Compose in the following way.
The following example
// Get PlatformSystemBarsController through state management.
val systemBars = rememberSystemBarsController()
Notice
When using rememberSystemBarsController
, if the native SystemBarsController
has not been initialized, it will automatically call init
for initialization.
To avoid problems with interface performance, you should ensure that initialization operations are completed during the configuration phase of each platform, otherwise you should ensure that rememberSystemBarsController
is called before all content starts to be drawn.
The following is a detailed usage introduction of PlatformSystemBarsController
.
Most of the usage here will be consistent with ui-component → System Bars (Status Bars, Navigation Bars, etc).
Set the behavior of system bars.
This determines the system-controlled behavior when showing or hiding system bars.
The following example
systemBars.behavior = PlatformSystemBarBehavior.Immersive
The following are all behaviors provided in PlatformSystemBarBehavior
, those marked with *
are the default behaviors.
Behavior | Platform | Description |
---|---|---|
Default | All | Default behavior controlled by the system. |
*Immersive | Android | A system bar that can be popped up by gesture sliding in full screen and displayed as a translucent system bar, and continues to hide after a period of time. |
iOS | The system bars can be revealed temporarily with system gestures when the status bars hide, but disappears after a period of time. |
Show, hide system bars.
The following example
// Enter immersive mode (full screen mode).
// Hide status bars and navigation bars, home indicator at the same time.
systemBars.hide(PlatformSystemBars.All)
// Separately control the status bars and navigation bars, home indicator.
systemBars.hide(PlatformSystemBars.StatusBars)
systemBars.hide(PlatformSystemBars.NavigationBars)
// Exit immersive mode (full screen mode).
// Show status bars and navigation bars, home indicator at the same time.
systemBars.show(PlatformSystemBars.ALL)
// Separately control the status bars and navigation bars, home indicator.
systemBars.show(PlatformSystemBars.StatusBars)
systemBars.show(PlatformSystemBars.NavigationBars)
Set the style of the system bars.
You can customize the appearance of the status bars and navigation bars, home indicator.
Notice
In systems below Android 6.0, the content of the status bars does not support inversion, if you set a bright color, it will be automatically processed as a semi-transparent mask.
However, for MIUI and Flyme systems that have added the inverse color function themselves, they will use their own private solutions to achieve the inverse color effect.
In systems below Android 8, the content of the navigation bars does not support inversion, and the processing method is the same as above.
In iOS, home indicator does not support setting darkContent
, its color is controlled by the system, but you can set the background color for it.
The following example
// Set the style of the status bars.
systemBars.statusBarStyle = PlatformSystemBarStyle(
// Set background color.
color = Color.White,
// Set content color.
darkContent = true
)
// Set the style of the navigation bars, home indicator.
systemBars.navigationBarStyle = PlatformSystemBarStyle(
// Set background color.
color = Color.White,
// Set content color.
darkContent = true
)
// You can set the style of the status bars and navigation bars, home indicator at once.
systemBars.setStyle(
statusBar = PlatformSystemBarStyle(
color = Color.White,
darkContent = true
),
navigationBar = PlatformSystemBarStyle(
color = Color.White,
darkContent = true
)
)
// You can also set the style of the status bars and navigation bars,
// home indicator at the same time.
systemBars.setStyle(
style = PlatformSystemBarStyle(
color = Color.White,
darkContent = true
)
)
The following are the preset styles provided in PlatformSystemBarStyle
, the ones marked with *
are the default styles.
Style | Description |
---|---|
Auto | The system dark mode is a pure black background + light content color, and the light mode is a pure white background + dark content color. |
*AutoTransparent | The light content color is used in the system dark mode, and the dark content color is used in the light mode, with a transparent background. |
Light | Pure white background + dark content color. |
LightScrim | Translucent pure white background + dark content color. |
LightTransparent | Transparent background + dark content color. |
Dark | Pure black background + light content color. |
DarkScrim | Translucent solid black background + light content color. |
DarkTransparent | Transparent background + light content color. |
Get the native controller.
You can obtain the native controller in the corresponding platform through the following methods, using commonMain
or in unsupported platforms will always return null
.
The following example
// Get the native controller.
val nativeController = systemBars.nativeController
Tips
BetterAndroid
also provides a native SystemBarsController
for iOS, its usage is basically the same as ui-component → System Bars (Status Bars, Navigation Bars, etc) except for the initialization function, normally you should not need to use it directly, and it will not be introduced in detail here.