mirror of
https://github.com/jlengrand/compose-multiplatform.git
synced 2026-03-10 08:11:20 +00:00
Upgrade to 1.2.0-beta01
This commit is contained in:
@@ -45,7 +45,7 @@ For the latest versions, see the [latest versions](https://github.com/JetBrains/
|
||||
```
|
||||
plugins {
|
||||
kotlin("jvm") version "1.6.10"
|
||||
id("org.jetbrains.compose") version "1.1.0"
|
||||
id("org.jetbrains.compose") version "1.2.0-beta01"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -81,7 +81,7 @@ import org.jetbrains.compose.compose
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.6.10"
|
||||
id("org.jetbrains.compose") version "1.1.0"
|
||||
id("org.jetbrains.compose") version "1.2.0-beta01"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,313 +1,313 @@
|
||||
# Image and in-app icons manipulations
|
||||
|
||||
## What is covered
|
||||
|
||||
In this tutorial we will show you how to work with images using Compose for Desktop.
|
||||
|
||||
## Loading images from resources
|
||||
|
||||
Using images from application resources is very simple. Suppose we have a PNG image that is placed in the `resources` directory in our project. For this tutorial we will use the image sample:
|
||||
|
||||
<img alt="Sample" src="sample.png" height="500" />
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
Image(
|
||||
painter = painterResource("sample.png"),
|
||||
contentDescription = "Sample",
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`painterResource` supports raster (BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP) and vector formats (SVG, [XML vector drawable](https://developer.android.com/guide/topics/graphics/vector-drawable-resources)).
|
||||
|
||||
<img alt="Resources" src="image_from_resources.png" height="375" />
|
||||
|
||||
## Loading images from device storage or network asynchronously
|
||||
|
||||
To load an image stored in the device memory (or from network) you can use `loadImageBitmap`, `loadSvgPainter` or `loadXmlImageVector`. The example below shows how to use them to load an image asynchronously.
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.loadSvgPainter
|
||||
import androidx.compose.ui.res.loadXmlImageVector
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.xml.sax.InputSource
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
val density = LocalDensity.current
|
||||
Column {
|
||||
AsyncImage(
|
||||
load = { loadImageBitmap(File("sample.png")) },
|
||||
painterFor = { remember { BitmapPainter(it) } },
|
||||
contentDescription = "Sample",
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
AsyncImage(
|
||||
load = { loadSvgPainter("https://github.com/JetBrains/compose-jb/raw/master/artwork/idea-logo.svg", density) },
|
||||
painterFor = { it },
|
||||
contentDescription = "Idea logo",
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
AsyncImage(
|
||||
load = { loadXmlImageVector(File("compose-logo.xml"), density) },
|
||||
painterFor = { rememberVectorPainter(it) },
|
||||
contentDescription = "Compose logo",
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> AsyncImage(
|
||||
load: suspend () -> T,
|
||||
painterFor: @Composable (T) -> Painter,
|
||||
contentDescription: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
) {
|
||||
val image: T? by produceState<T?>(null) {
|
||||
value = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
load()
|
||||
} catch (e: IOException) {
|
||||
// instead of printing to console, you can also write this to log,
|
||||
// or show some error placeholder
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
Image(
|
||||
painter = painterFor(image!!),
|
||||
contentDescription = contentDescription,
|
||||
contentScale = contentScale,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading from file with java.io API */
|
||||
|
||||
fun loadImageBitmap(file: File): ImageBitmap =
|
||||
file.inputStream().buffered().use(::loadImageBitmap)
|
||||
|
||||
fun loadSvgPainter(file: File, density: Density): Painter =
|
||||
file.inputStream().buffered().use { loadSvgPainter(it, density) }
|
||||
|
||||
fun loadXmlImageVector(file: File, density: Density): ImageVector =
|
||||
file.inputStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
/* Loading from network with java.net API */
|
||||
|
||||
fun loadImageBitmap(url: String): ImageBitmap =
|
||||
URL(url).openStream().buffered().use(::loadImageBitmap)
|
||||
|
||||
fun loadSvgPainter(url: String, density: Density): Painter =
|
||||
URL(url).openStream().buffered().use { loadSvgPainter(it, density) }
|
||||
|
||||
fun loadXmlImageVector(url: String, density: Density): ImageVector =
|
||||
URL(url).openStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
/* Loading from network with Ktor client API (https://ktor.io/docs/client.html). */
|
||||
|
||||
/*
|
||||
|
||||
suspend fun loadImageBitmap(url: String): ImageBitmap =
|
||||
urlStream(url).use(::loadImageBitmap)
|
||||
|
||||
suspend fun loadSvgPainter(url: String, density: Density): Painter =
|
||||
urlStream(url).use { loadSvgPainter(it, density) }
|
||||
|
||||
suspend fun loadXmlImageVector(url: String, density: Density): ImageVector =
|
||||
urlStream(url).use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
@OptIn(KtorExperimentalAPI::class)
|
||||
private suspend fun urlStream(url: String) = HttpClient(CIO).use {
|
||||
ByteArrayInputStream(it.get(url))
|
||||
}
|
||||
|
||||
*/
|
||||
```
|
||||
|
||||
<img alt="Storage" src="image_from_resources2.png" height="356" />
|
||||
|
||||
[PNG](sample.png)
|
||||
|
||||
[SVG](../../artwork/idea-logo.svg)
|
||||
|
||||
[XML vector drawable](../../artwork/compose-logo.xml)
|
||||
|
||||
## Drawing images using Canvas
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Paint
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.graphics.withSave
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.loadSvgPainter
|
||||
import androidx.compose.ui.res.loadXmlImageVector
|
||||
import androidx.compose.ui.res.useResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
import org.xml.sax.InputSource
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
val density = LocalDensity.current // to calculate the intrinsic size of vector images (SVG, XML)
|
||||
|
||||
val sample = remember {
|
||||
useResource("sample.png", ::loadImageBitmap)
|
||||
}
|
||||
val ideaLogo = remember {
|
||||
useResource("idea-logo.svg") { loadSvgPainter(it, density) }
|
||||
}
|
||||
val composeLogo = rememberVectorPainter(
|
||||
remember {
|
||||
useResource("compose-logo.xml") { loadXmlImageVector(InputSource(it), density) }
|
||||
}
|
||||
)
|
||||
|
||||
Canvas(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
drawIntoCanvas { canvas ->
|
||||
canvas.withSave {
|
||||
canvas.drawImage(sample, Offset.Zero, Paint())
|
||||
canvas.translate(sample.width.toFloat(), 0f)
|
||||
with(ideaLogo) {
|
||||
draw(ideaLogo.intrinsicSize)
|
||||
}
|
||||
canvas.translate(ideaLogo.intrinsicSize.width, 0f)
|
||||
with(composeLogo) {
|
||||
draw(Size(100f, 100f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[PNG](sample.png)
|
||||
|
||||
[SVG](../../artwork/idea-logo.svg)
|
||||
|
||||
[XML vector drawable](../../artwork/compose-logo.xml)
|
||||
|
||||
## Setting the application window icon
|
||||
|
||||
You can set the icon for the window via parameter in the `Window` function.
|
||||
|
||||
Note that to change the icon on the taskbar on some OS (macOs), you should change icon in [build.gradle](/tutorials/Native_distributions_and_local_execution#app-icon)
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.paint
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
|
||||
fun main() = application {
|
||||
val icon = painterResource("sample.png")
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
icon = icon
|
||||
) {
|
||||
Box(Modifier.paint(icon).fillMaxSize())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<img alt="Window icon" src="window_icon.png" height="371" />
|
||||
|
||||
In case of `singleWindowApplication` usage, you can use the following approach:
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.useResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
|
||||
fun main() {
|
||||
val icon = BitmapPainter(useResource("sample.png", ::loadImageBitmap))
|
||||
singleWindowApplication(icon = icon) {
|
||||
Text("Hello World!")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Setting the application tray icon
|
||||
|
||||
You can create a tray icon for your application:
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.Tray
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
|
||||
fun main() = application {
|
||||
val icon = painterResource("sample.png")
|
||||
|
||||
Tray(
|
||||
icon = icon,
|
||||
menu = {
|
||||
Item("Quit App", onClick = ::exitApplication)
|
||||
}
|
||||
)
|
||||
|
||||
Window(onCloseRequest = ::exitApplication, icon = icon) {
|
||||
Image(
|
||||
painter = icon,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<img alt="Tray icon" src="tray_icon.png" height="479" />
|
||||
# Image and in-app icons manipulations
|
||||
|
||||
## What is covered
|
||||
|
||||
In this tutorial we will show you how to work with images using Compose for Desktop.
|
||||
|
||||
## Loading images from resources
|
||||
|
||||
Using images from application resources is very simple. Suppose we have a PNG image that is placed in the `resources` directory in our project. For this tutorial we will use the image sample:
|
||||
|
||||
<img alt="Sample" src="sample.png" height="500" />
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
Image(
|
||||
painter = painterResource("sample.png"),
|
||||
contentDescription = "Sample",
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
`painterResource` supports raster (BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP) and vector formats (SVG, [XML vector drawable](https://developer.android.com/guide/topics/graphics/vector-drawable-resources)).
|
||||
|
||||
<img alt="Resources" src="image_from_resources.png" height="375" />
|
||||
|
||||
## Loading images from device storage or network asynchronously
|
||||
|
||||
To load an image stored in the device memory (or from network) you can use `loadImageBitmap`, `loadSvgPainter` or `loadXmlImageVector`. The example below shows how to use them to load an image asynchronously.
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.loadSvgPainter
|
||||
import androidx.compose.ui.res.loadXmlImageVector
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.xml.sax.InputSource
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
val density = LocalDensity.current
|
||||
Column {
|
||||
AsyncImage(
|
||||
load = { loadImageBitmap(File("sample.png")) },
|
||||
painterFor = { remember { BitmapPainter(it) } },
|
||||
contentDescription = "Sample",
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
AsyncImage(
|
||||
load = { loadSvgPainter("https://github.com/JetBrains/compose-jb/raw/master/artwork/idea-logo.svg", density) },
|
||||
painterFor = { it },
|
||||
contentDescription = "Idea logo",
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
AsyncImage(
|
||||
load = { loadXmlImageVector(File("compose-logo.xml"), density) },
|
||||
painterFor = { rememberVectorPainter(it) },
|
||||
contentDescription = "Compose logo",
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier.width(200.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> AsyncImage(
|
||||
load: suspend () -> T,
|
||||
painterFor: @Composable (T) -> Painter,
|
||||
contentDescription: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
) {
|
||||
val image: T? by produceState<T?>(null) {
|
||||
value = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
load()
|
||||
} catch (e: IOException) {
|
||||
// instead of printing to console, you can also write this to log,
|
||||
// or show some error placeholder
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
Image(
|
||||
painter = painterFor(image!!),
|
||||
contentDescription = contentDescription,
|
||||
contentScale = contentScale,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading from file with java.io API */
|
||||
|
||||
fun loadImageBitmap(file: File): ImageBitmap =
|
||||
file.inputStream().buffered().use(::loadImageBitmap)
|
||||
|
||||
fun loadSvgPainter(file: File, density: Density): Painter =
|
||||
file.inputStream().buffered().use { loadSvgPainter(it, density) }
|
||||
|
||||
fun loadXmlImageVector(file: File, density: Density): ImageVector =
|
||||
file.inputStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
/* Loading from network with java.net API */
|
||||
|
||||
fun loadImageBitmap(url: String): ImageBitmap =
|
||||
URL(url).openStream().buffered().use(::loadImageBitmap)
|
||||
|
||||
fun loadSvgPainter(url: String, density: Density): Painter =
|
||||
URL(url).openStream().buffered().use { loadSvgPainter(it, density) }
|
||||
|
||||
fun loadXmlImageVector(url: String, density: Density): ImageVector =
|
||||
URL(url).openStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
/* Loading from network with Ktor client API (https://ktor.io/docs/client.html). */
|
||||
|
||||
/*
|
||||
|
||||
suspend fun loadImageBitmap(url: String): ImageBitmap =
|
||||
urlStream(url).use(::loadImageBitmap)
|
||||
|
||||
suspend fun loadSvgPainter(url: String, density: Density): Painter =
|
||||
urlStream(url).use { loadSvgPainter(it, density) }
|
||||
|
||||
suspend fun loadXmlImageVector(url: String, density: Density): ImageVector =
|
||||
urlStream(url).use { loadXmlImageVector(InputSource(it), density) }
|
||||
|
||||
@OptIn(KtorExperimentalAPI::class)
|
||||
private suspend fun urlStream(url: String) = HttpClient(CIO).use {
|
||||
ByteArrayInputStream(it.get(url))
|
||||
}
|
||||
|
||||
*/
|
||||
```
|
||||
|
||||
<img alt="Storage" src="image_from_resources2.png" height="356" />
|
||||
|
||||
[PNG](sample.png)
|
||||
|
||||
[SVG](../../artwork/idea-logo.svg)
|
||||
|
||||
[XML vector drawable](../../artwork/compose-logo.xml)
|
||||
|
||||
## Drawing images using Canvas
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Paint
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.graphics.withSave
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.loadSvgPainter
|
||||
import androidx.compose.ui.res.loadXmlImageVector
|
||||
import androidx.compose.ui.res.useResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
import org.xml.sax.InputSource
|
||||
|
||||
fun main() = singleWindowApplication {
|
||||
val density = LocalDensity.current // to calculate the intrinsic size of vector images (SVG, XML)
|
||||
|
||||
val sample = remember {
|
||||
useResource("sample.png", ::loadImageBitmap)
|
||||
}
|
||||
val ideaLogo = remember {
|
||||
useResource("idea-logo.svg") { loadSvgPainter(it, density) }
|
||||
}
|
||||
val composeLogo = rememberVectorPainter(
|
||||
remember {
|
||||
useResource("compose-logo.xml") { loadXmlImageVector(InputSource(it), density) }
|
||||
}
|
||||
)
|
||||
|
||||
Canvas(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
drawIntoCanvas { canvas ->
|
||||
canvas.withSave {
|
||||
canvas.drawImage(sample, Offset.Zero, Paint())
|
||||
canvas.translate(sample.width.toFloat(), 0f)
|
||||
with(ideaLogo) {
|
||||
draw(ideaLogo.intrinsicSize)
|
||||
}
|
||||
canvas.translate(ideaLogo.intrinsicSize.width, 0f)
|
||||
with(composeLogo) {
|
||||
draw(Size(100f, 100f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[PNG](sample.png)
|
||||
|
||||
[SVG](../../artwork/idea-logo.svg)
|
||||
|
||||
[XML vector drawable](../../artwork/compose-logo.xml)
|
||||
|
||||
## Setting the application window icon
|
||||
|
||||
You can set the icon for the window via parameter in the `Window` function.
|
||||
|
||||
Note that to change the icon on the taskbar on some OS (macOs), you should change icon in [build.gradle](/tutorials/Native_distributions_and_local_execution#app-icon)
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.paint
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
|
||||
fun main() = application {
|
||||
val icon = painterResource("sample.png")
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
icon = icon
|
||||
) {
|
||||
Box(Modifier.paint(icon).fillMaxSize())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<img alt="Window icon" src="window_icon.png" height="371" />
|
||||
|
||||
In case of `singleWindowApplication` usage, you can use the following approach:
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.res.loadImageBitmap
|
||||
import androidx.compose.ui.res.useResource
|
||||
import androidx.compose.ui.window.singleWindowApplication
|
||||
|
||||
fun main() {
|
||||
val icon = BitmapPainter(useResource("sample.png", ::loadImageBitmap))
|
||||
singleWindowApplication(icon = icon) {
|
||||
Text("Hello World!")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Setting the application tray icon
|
||||
|
||||
You can create a tray icon for your application:
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.window.Tray
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
|
||||
fun main() = application {
|
||||
val icon = painterResource("sample.png")
|
||||
|
||||
Tray(
|
||||
icon = icon,
|
||||
menu = {
|
||||
Item("Quit App", onClick = ::exitApplication)
|
||||
}
|
||||
)
|
||||
|
||||
Window(onCloseRequest = ::exitApplication, icon = icon) {
|
||||
Image(
|
||||
painter = icon,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<img alt="Tray icon" src="tray_icon.png" height="479" />
|
||||
|
||||
@@ -39,7 +39,7 @@ pluginManagement {
|
||||
// Add compose gradle plugin
|
||||
plugins {
|
||||
kotlin("multiplatform") version "1.6.10"
|
||||
id("org.jetbrains.compose") version "1.1.0"
|
||||
id("org.jetbrains.compose") version "1.2.0-beta01"
|
||||
}
|
||||
|
||||
// Add maven repositories
|
||||
|
||||
Reference in New Issue
Block a user