Skip to content

Commit 8789ceb

Browse files
feat: replace Coil with Landscapist for image loading
This commit replaces the Coil 3 image loading library with Landscapist in the sample app for better performance and features. It also includes several dependency updates and code refactoring. Key changes: - **Image Loading**: - Replaced `rememberAsyncImagePainter` from Coil with `CoilImage` from Landscapist to display picked images. - **Dependency Updates**: - `mavenPublish` to `0.36.0`. - `spotless` to `8.2.1`. - `activityCompose` to `1.12.3`. - `composeBom` to `2026.01.01`. - Added the Landscapist BOM (`2.9.3`). - **Code Refactoring**: - Refactored `FilePickerWithResultList.kt` to use separate composables (`ImageItem`, `VideoItem`, `OtherFileItem`) for displaying different file types. - Added `@Immutable` annotation to the `PickedFile` data class. - Minor code style improvements in `Theme.kt` and `FilePickerResultContracts.kt`. - **Bug Fix**: - Removed an unnecessary safe call (`?.`) in `PopUpActivity.kt` when accessing `selectedFilePaths`, as the property is non-nullable.
1 parent 792981c commit 8789ceb

6 files changed

Lines changed: 112 additions & 67 deletions

File tree

filepickerlibrary/src/main/java/com/nareshchocha/filepickerlibrary/FilePickerResultContracts.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,28 @@ class FilePickerResultContracts private constructor() {
191191

192192
val configType = intent.getStringExtra(Const.BundleExtras.CONFIG_TYPE)
193193
return when (configType) {
194-
ImageCaptureConfig::class.java.name -> ImageCapture().parseResult(resultCode, intent)
195-
VideoCaptureConfig::class.java.name -> VideoCapture().parseResult(resultCode, intent)
196-
PickMediaConfig::class.java.name -> PickMedia().parseResult(resultCode, intent)
197-
DocumentFilePickerConfig::class.java.name ->
194+
ImageCaptureConfig::class.java.name -> {
195+
ImageCapture().parseResult(resultCode, intent)
196+
}
197+
198+
VideoCaptureConfig::class.java.name -> {
199+
VideoCapture().parseResult(resultCode, intent)
200+
}
201+
202+
PickMediaConfig::class.java.name -> {
203+
PickMedia().parseResult(resultCode, intent)
204+
}
205+
206+
DocumentFilePickerConfig::class.java.name -> {
198207
PickDocumentFile().parseResult(
199208
resultCode,
200209
intent
201210
)
211+
}
202212

203-
else -> FilePickerResult(errorMessage = "Unknown file type")
213+
else -> {
214+
FilePickerResult(errorMessage = "Unknown file type")
215+
}
204216
}
205217
}
206218
}

filepickerlibrary/src/main/java/com/nareshchocha/filepickerlibrary/ui/activitys/PopUpActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ internal class PopUpActivity : ComponentActivity() {
5050
if (!result.selectedFileUris.isNullOrEmpty()) {
5151
setSuccessResult(
5252
result.selectedFileUris,
53-
result?.selectedFilePaths?.toArrayList()
53+
result.selectedFilePaths?.toArrayList()
5454
)
5555
} else if (result.selectedFileUri != null) {
5656
setSuccessResult(result.selectedFileUri, result.selectedFilePath)

gradle/libs.versions.toml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
[versions]
22
agp = "9.0.0"
3-
mavenPublish = "0.35.0"
3+
mavenPublish = "0.36.0"
44
kotlin = "2.3.0"
55
detekt = "1.23.8"
6-
spotless = "8.1.0"
6+
spotless = "8.2.1"
7+
8+
79

810
# build config
911
compileSdk = "36"
@@ -15,8 +17,11 @@ jdkVersion = "VERSION_24"
1517
core-splashscreen = "1.2.0"
1618

1719
# compose
18-
activityCompose = "1.12.2"
19-
composeBom = "2026.01.00"
20+
activityCompose = "1.12.3"
21+
composeBom = "2026.01.01"
22+
23+
# landscapist
24+
landscapistBom = "2.9.3"
2025

2126
[libraries]
2227
# core
@@ -30,6 +35,9 @@ androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
3035
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
3136
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
3237
androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
38+
# landscapist
39+
skydoves-landscapist-bom = { group = "com.github.skydoves", name = "landscapist-bom", version.ref = "landscapistBom" }
40+
skydoves-landscapist-coil = { group = "com.github.skydoves", name = "landscapist-coil" }
3341

3442
# testing compose
3543
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }

sample/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ dependencies {
7171
implementation(libs.androidx.material3)
7272
implementation(libs.androidx.material.icons.extended)
7373

74-
implementation("io.coil-kt.coil3:coil-compose:3.2.0")
74+
// landscapist
75+
implementation(libs.skydoves.landscapist.bom)
76+
implementation(libs.skydoves.landscapist.coil)
7577

7678
// File Picker
7779
implementation(project(":filepickerlibrary"))
78-
// implementation(libs.androidx.lifecycle.runtime.ktx)
7980

8081
// testing compose
8182
androidTestImplementation(platform(libs.androidx.compose.bom))

sample/src/main/java/com/nareshchocha/filepicker/components/FilePickerWithResultList.kt

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.nareshchocha.filepicker.components
22

33
import android.net.Uri
4-
import androidx.compose.foundation.Image
54
import androidx.compose.foundation.background
65
import androidx.compose.foundation.layout.Arrangement
76
import androidx.compose.foundation.layout.Column
@@ -19,12 +18,15 @@ import androidx.compose.material3.Icon
1918
import androidx.compose.material3.MaterialTheme
2019
import androidx.compose.material3.Text
2120
import androidx.compose.runtime.Composable
21+
import androidx.compose.runtime.Immutable
22+
import androidx.compose.ui.Alignment
2223
import androidx.compose.ui.Modifier
2324
import androidx.compose.ui.layout.ContentScale
2425
import androidx.compose.ui.text.font.FontWeight
2526
import androidx.compose.ui.tooling.preview.Preview
2627
import androidx.compose.ui.unit.dp
27-
import coil3.compose.rememberAsyncImagePainter
28+
import com.skydoves.landscapist.ImageOptions
29+
import com.skydoves.landscapist.coil.CoilImage
2830

2931
@Composable
3032
fun FilePickerWithResultList(pickedFiles: List<PickedFile>) {
@@ -33,62 +35,79 @@ fun FilePickerWithResultList(pickedFiles: List<PickedFile>) {
3335
verticalArrangement = Arrangement.spacedBy(8.dp),
3436
modifier = Modifier.fillMaxHeight()
3537
) {
36-
items(pickedFiles) { file ->
37-
when (file.type) {
38-
"image" ->
39-
Image(
40-
painter = rememberAsyncImagePainter(file.uri),
41-
contentDescription = null,
42-
modifier = Modifier.size(100.dp),
43-
contentScale = ContentScale.Crop
44-
)
38+
items(items = pickedFiles, key = { it.uri.toString() }) { file ->
39+
FileItem(file = file)
40+
}
41+
}
42+
}
4543

46-
"video" -> {
47-
Row(
48-
modifier =
49-
Modifier
50-
.background(
51-
color = MaterialTheme.colorScheme.secondaryContainer,
52-
shape = RoundedCornerShape(8.dp)
53-
).padding(12.dp)
54-
) {
55-
Icon(
56-
imageVector = Icons.Default.Videocam,
57-
contentDescription = "Video",
58-
tint = MaterialTheme.colorScheme.outline,
59-
modifier = Modifier.padding(end = 8.dp)
60-
)
61-
Text(
62-
text = "Video: ${file.uri}",
63-
style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold)
64-
)
65-
}
66-
}
44+
@Composable
45+
private fun FileItem(file: PickedFile) {
46+
when (file.type) {
47+
"image" -> ImageItem(uri = file.uri)
48+
"video" -> VideoItem(uri = file.uri)
49+
else -> OtherFileItem(file = file)
50+
}
51+
}
6752

68-
else -> {
69-
Column(
70-
modifier =
71-
Modifier
72-
.background(
73-
color = MaterialTheme.colorScheme.outline,
74-
shape = RoundedCornerShape(8.dp)
75-
).padding(12.dp)
76-
) {
77-
Text(
78-
text = "URI: ${file.uri}",
79-
style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold)
80-
)
81-
Text(
82-
text = "Path: ${file.filePath ?: "N/A"}",
83-
style = MaterialTheme.typography.bodySmall
84-
)
85-
}
86-
}
87-
}
88-
}
53+
@Composable
54+
private fun ImageItem(uri: Uri) {
55+
CoilImage(
56+
imageModel = { uri }, // loading a network image or local resource using an URL.
57+
imageOptions =
58+
ImageOptions(
59+
contentScale = ContentScale.Crop,
60+
alignment = Alignment.Center
61+
),
62+
modifier = Modifier.size(100.dp)
63+
)
64+
}
65+
66+
@Composable
67+
private fun VideoItem(uri: Uri) {
68+
Row(
69+
modifier =
70+
Modifier
71+
.background(
72+
color = MaterialTheme.colorScheme.secondaryContainer,
73+
shape = RoundedCornerShape(8.dp)
74+
).padding(12.dp)
75+
) {
76+
Icon(
77+
imageVector = Icons.Default.Videocam,
78+
contentDescription = "Video",
79+
tint = MaterialTheme.colorScheme.outline,
80+
modifier = Modifier.padding(end = 8.dp)
81+
)
82+
Text(
83+
text = "Video: $uri",
84+
style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold)
85+
)
86+
}
87+
}
88+
89+
@Composable
90+
private fun OtherFileItem(file: PickedFile) {
91+
Column(
92+
modifier =
93+
Modifier
94+
.background(
95+
color = MaterialTheme.colorScheme.outline,
96+
shape = RoundedCornerShape(8.dp)
97+
).padding(12.dp)
98+
) {
99+
Text(
100+
text = "URI: ${file.uri}",
101+
style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold)
102+
)
103+
Text(
104+
text = "Path: ${file.filePath ?: "N/A"}",
105+
style = MaterialTheme.typography.bodySmall
106+
)
89107
}
90108
}
91109

110+
@Immutable
92111
data class PickedFile(
93112
val uri: Uri,
94113
val type: String, // "image", "video", "other"

sample/src/main/java/com/nareshchocha/filepicker/ui/theme/Theme.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,13 @@ fun FilePickerTheme(
3838
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
3939
}
4040

41-
darkTheme -> DarkColorScheme
42-
else -> LightColorScheme
41+
darkTheme -> {
42+
DarkColorScheme
43+
}
44+
45+
else -> {
46+
LightColorScheme
47+
}
4348
}
4449

4550
MaterialTheme(

0 commit comments

Comments
 (0)