Resources generation in Kotlin Multiplatform.
// build.gradle.kts (project)
buildscript {
dependencies {
classpath("io.github.skeptick.libres:gradle-plugin:1.1.8")
}
}
// build.gradle.kts (module)
plugins {
id("io.github.skeptick.libres")
}
libres {
generatedClassName = "MainRes" // "Res" by default
generateNamedArguments = true // false by default
baseLocaleLanguageCode = "ru" // "en" by default
camelCaseNamesForAppleFramework = true // false by default
}
- Android, JVM, iOS, MacOS and JS in Kotlin Multiplatform projects.
- Pure Android or JVM projects with Kotlin.
Kotlin | 1.6.20+ |
Android | 4.1+ (API level 16) |
Android Gradle Plugin | 7.0+ |
iOS | 13+ (when using vector icons) |
Also you need to use CocoaPods and
CocoaPods Gradle plugin
to export images to iOS project.
If you aren't reusing images in iOS then this condition is optional.
Resources must be stored in {yourSourceSetName}/libres
Multiplatform:
├── commonMain
│ ├── kotlin
│ └── libres
│ ├── images
│ │ ├── vector_image.svg
│ │ └── raster_image.png
│ └── strings
│ ├── strings_en.xml
│ └── strings_ru.xml
Android or JVM:
├── main
│ ├── java
│ └── libres
│ ├── images
│ │ ├── vector_image.svg
│ │ └── raster_image.png
│ └── strings
│ ├── strings_en.xml
│ └── strings_ru.xml
Strings are stored in the usual for Android form in xml
files.
The file postfix must contain the code of the language for which the strings are intended. E.g.: my_app_strings_en.xml
For each of the languages you can create several files and they will be merged during compilation.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="simple_string">Hello!</string>
<string name="string_with_arguments">Hello ${name}!</string>
<plurals name="plural_string">
<item quantity="one">resource</item>
<item quantity="other">resources</item>
</plurals>
</resources>
Kotlin:
MainRes.string.simple_string
MainRes.string.string_with_arguments.format(name = "John")
MainRes.string.plural_string.format(5)
Swift:
MainRes.shared.string.simple_string
Note In the example above
MainRes.string.simple_string
will return a string, so for better localization support it's not recommended to store the value. Get it directly at the place where it's displayed in the UI. This seems familiar but the ability to work directly with strings instead of resource IDs can be misused.
Supported formats:
- PNG
- JPG
- WEBP (Android 4.3+, iOS 14+)
- SVG (iOS 13+)
For Android SVG are converted to vector drawable, for other platforms they copied as is.
The image filename can contain modifiers in parentheses listed through underscores.
orig
Used for iOS. Marks the image as
Original
(similar toRender As: Original Image
in the Assets Manager in XCode). Recommended for multicolor images.
size
Applies to bitmaps. Reduces the image resolution to the specified size.
- For Android images are generated from mdpi to xxxhdpi (where mdpi is 1:1 in pixels to the specified size)
- For iOS images are generated from 1x to 3x (where 1x is 1:1 in pixels to the specified size)
- For JVM and JS a single image of the specified size is generated.
Filename examples:
some_hd_image_(100).jpg
app_logo_(orig).svg
my_colorful_bitmap_(orig)_(150).png
Kotlin:
MainRes.image.some_hd_image
MainRes.image.app_logo
MainRes.image.my_colorful_bitmap
Swift:
MainRes.shared.image.some_hd_image // -> UIImage
How to export an image from Figma
To obtain bundle of png images with different resolutions (e.g. mdpi - xxxhdpi on Android) do the following steps
- Export image from Figma with x4 scale (it matches to the biggest used size (xxxhdpi on Android))
- Put it to libres/images package
- Remember the biggest side value of image represented in Figma
- Rename image with the value of the biggest side: from pic.png to pic_(orig)_({side_value}) or pic_({side_value})
Sample: Image size in Figma is 240x89. Final image name is pic_(orig)_(240).png
// build.gradle.kts (module)
kotlin {
commonMain {
dependencies {
implementation("io.github.skeptick.libres:libres-compose:1.1.8")
}
}
}
This artifact provides painterResource
function that can be used
to get Painter
from io.github.skeptick.libres.Image
in common code.
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end
Workaround for versions 7+:
// build.gradle.kts (module)
android {
...
...
sourceSets {
named("main") {
res.srcDir("build/generated/libres/android/resources")
}
}
}