https://kotlinlang.org logo
Join Slack
Powered by
# compose
  • y

    yousef shaaban

    05/04/2025, 4:09 PM
    Hello Team Is there any library load gif for ComposeMulti platform? Or How Handel gif in splash know it is finish to move second screen ?
    c
    c
    • 3
    • 13
  • k

    krzysztof

    05/04/2025, 7:58 PM
    Hey, I’m using compose navigation with a custom nav type, where I subclass NavType to serialize/deserialize my type. I noticed that if a url value is stored in my type’s property, I get an error
    Navigation destination that matches request (…) cannot be found in the navigation graph
    . I found out that uri decoding the value in overridden
    serializeAsValue
    method makes it work, but I cannot find it anywhere mentioned it documentation. Is this the right approach or is there something I’m missing?
    i
    • 2
    • 4
  • c

    Colton Idle

    05/04/2025, 8:08 PM
    Saw a code example like this...
    Copy code
    @Composable
    fun InstrumentsList() {
        var instruments by remember { mutableStateOf<List<Instrument>>(listOf()) }
        LaunchedEffect(Unit) {
            withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
                instruments = supabase.from("instruments")
                                  .select().decodeList<Instrument>()
            }
        }
    Could you just move the work from the LaunchedEffect to the remember {}.block?
    m
    e
    +2
    • 5
    • 19
  • e

    eneim

    05/05/2025, 12:20 PM
    Hi team, I notice something weird in this source code of Android: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]pose/ui/platform/Wrapper.android.kt;l=62?q=Wrapper.android.kt (It may be more suitable to post in #C04TPPEQKEJ but I don't know who should this message is to. Perhaps @Ian Lake). I wonder why it has to
    removeAllViews()
    when
    childCount
    is
    <= 0
    in the
    else
    flow. In stead, should the
    removeAllViews()
    is called right before creating a new
    AndroidComposeView
    instance and in the same block:
    Copy code
    // Suggestion:
    val composeView = if (childCount > 0) { getChildAt(0) as? AndroidComposeView } else { null } ?: /* at this point we know the parent doesn't contain any AndroidComposeView, regardless of its childCount, so we have to ensure it is empty and then add a new AndroidComposeView to it */ run {
        removeAllViews()
        // Create a new AndroidComposeView and "also" add it to "this".
    }
    From the code, it seems that, if
    childCount > 0
    but the first child is not an
    AndroidComposeView
    , the parent doesn't clear it before adding the newly created one. Also, (AFAIK) even when
    childCount <= 0
    , calling
    removeAllViews()
    will cause a layout traversal so doing it seems to be unnecessary.
    s
    • 2
    • 11
  • e

    eneim

    05/05/2025, 12:53 PM
    Another observation at https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]ose/ui/platform/Wrapper.android.kt;l=118?q=Wrapper.android.kt So I understand that a
    WrappedComposition
    will be reused under some conditions to optimize the performance (e.g., using in a PoolingContainer like RecyclerView). However, in such case, it seems that
    WrapperComposition.addedToLifecycle
    field is never updated after the first set to non-null call. I guess the class assumes that the containing AndroidComposeView is added to at most one lifecycle? But in the case of RecyclerView, we can specify a RecycledViewPool at the Activity's scope, whiles RecyclerView instances using that Pool are in Fragments of that Activity --> an AndroidComposeView could be (re)used across different Lifecycle (i.e. different Fragments). Combine with the code in the 2nd screenshot (onStateChanged), I can see that: if a AndroidComposeView is used to a Fragment A, then re-used-without-decomposing in a Fragment B, if the destruction of Fragment A happens after the creation of Fragment B, then the WrappedComposition will be disposed and the UI is gone. JFYI, the Epoxy library utilizes this Activity-bound Pool by default & I could reproduce the UI-be-gone issue above (not as high confidence, but still). I assume any implementation using a similar Pool has this issue, not Epoxy-specific issue. I think a code change like below can address it:
    Copy code
    // WrappedComposition.setContent, line 118.
                    val lifecycle = it.lifecycleOwner.lifecycle
                    lastContent = content
                    if (addedToLifecycle != lifecycle) {
                        addedToLifecycle?.removeObserver(this@WrappedComposition) // Added to a new Lifecycle, so it must detach from the old one, if any.
                        addedToLifecycle = lifecycle
                        // this will call ON_CREATE synchronously if we already created
                        lifecycle.addObserver(this)
                    } // else ...
    s
    • 2
    • 2
  • a

    ankur samarya

    05/05/2025, 12:53 PM
    Hey, Can someone please help me in why
    Bar
    is not recomposing with the new lambda instance? In this example code, I am creating a new instance of
    onBarClick
    every time the state changes. Since it's a new instance, the
    Bar
    should recompose as well — but it's not. I've disabled strong skipping using
    enableStrongSkippingMode = false
    .
    Copy code
    @Composable
    fun Foo() {
        val state = remember {
            mutableIntStateOf(1)
        }
    
        val onBarClick = {}
    
        Log.d("logs", "Foo Recomposition ${onBarClick}" )
    
        Column {
            Text(text = "Value ${state.value}")
            
            Bar(onBarClick = onBarClick)
    
            Button(onClick = { state.value++ }) {
                Text(text = "Increment")
            }
        }
    }
    
    @Composable
    fun Bar(onBarClick: () -> Unit) {
        Log.d("logs", "Bar Recomposition" )
        Button(onClick = onBarClick) {
            Text(text = "Dummy Button")
        }
    }
    Thanks
    e
    w
    +2
    • 5
    • 16
  • m

    Madhur

    05/05/2025, 1:14 PM
    I am trying to import
    ComposeUIViewController
    from
    androidx.compose.ui.window
    but I get error saying class not found. I can confirm it not being present at
    External Dependencies > androidx.compose.ui.window
    . However, I can see it working in the Confetti sample with the same versions. When I try to locate
    ComposeUIViewController
    in this project it shows the path as
    .kotlin > metadata > kotlinTransformedMetadataLibraries > org.jetbrains.compose.ui-ui-1.7.3-uikitMain-bkbtDw.klib > default > linkdata > package_androidx.compose.ui.window
    ? Can someone help me on how is the linking for ComposeUIViewController happening in Confetti example?
  • a

    Arne Vanstraeseele

    05/05/2025, 2:08 PM
    Hi, I have a form in my app but i want to have te form scrolled up with the IME padding. Is that already supported in compose multiplatform?
  • s

    Stefan Oltmann

    05/05/2025, 3:29 PM
    In a recent code review I had the discussion if my way to load images in SKIA is wrong. I use to do this:
    Copy code
    val imageBitmap = makeImageFromByteArray(bytes).toComposeImageBitmap()
    The suggestion is to do this instead:
    Copy code
    val image = makeImageFromByteArray(bytes)
    
    val imageBitmap = image.use {
        it.toComposeImageBitmap()
    }
    The reason behind that is that the SKIA image will not be closed after the copy process and the native resources not be freed up... That may be one of the issues for memory issues I experienced on iOS. I don't find anything how to properly use
    toComposeImageBitmap()
    Is is true that the SKIA image behind will not be freed immediately after a method like this completed?
    Copy code
    fun createImage(bytes: ByteArray) = makeImageFromByteArray(bytes).toComposeImageBitmap()
    Is there a way/need to dispose()/close() the ImageBitmap after the Composable disposes?
    👀 1
    e
    • 2
    • 2
  • h

    Howaye

    05/05/2025, 9:39 PM
    Hello, Is there issues trying to use
    CompositionLocal
    to pass composable lambda to a child composable? Something like below.
    Copy code
    val LocalComposable = compositionLocalOf<@Composable (Modifier) -> Unit> { { Box {} } }
    
    @Composable
    fun DescendantDeepInHiearchy() {
        LocalComposable.current
    }
    I did see in the Alternatives to Consider section about IOC, mentioning composable lambdas benefiting from IOC. I didn't find whether it would be a good or bad idea to to use composable lambdas in
    CompositionLocal
    j
    • 2
    • 1
  • d

    Dylan Sale

    05/05/2025, 11:42 PM
    Hi! Does anyone know if context parameters will work with Composable functions? I can't find anything on it.
    j
    s
    • 3
    • 3
  • u

    Usman

    05/06/2025, 12:45 AM
    Dose Here any body know how to modularize your compose mltiplatform project
  • a

    AmrJyniat

    05/06/2025, 10:21 AM
    Hi I have tabs with a regular font. When selecting a tab, it should be in bold, my issue is the extra width that comes with the bold style. How to make the text width fixed regardless of the font weight?
    CleanShot 2025-05-06 at 13.19.56.mp4
    🧵 1
    m
    • 2
    • 3
  • a

    Avinash

    05/06/2025, 10:25 AM
    Hi! Can someone help me with the Material3.ModalBottomSheet overlapping the system navigation buttons issue when enableEdgeToEdge is disabled? I found a few references in IssueTracker, but they don’t seem to work. I tried adding bottom padding to the root content of ModalBottomSheet like .padding(bottom = WindowInsets.navigationBarsIgnoringVisibility.asPaddingValues().calculateBottomPadding()) It does fix the issue in portrait mode, but when the orientation is turned to the right, the left side of the bottom sheet still gets overlapped.
    Screen_Recording_20250506_153220_Compose.mp4
  • g

    Gabriel Stefan

    05/06/2025, 10:40 AM
    Hey everyone 👋 Quick question, as my attempts at searching returned nothing In compose, when dealing with nullable types, which is more idiomatic of the two?
    Copy code
    @Composable
    fun MyComposable(input: Type?) {
      if (input != null) {
         XComposable(input)
      } else {
         YComposable()
      }
    }
    vs
    Copy code
    @Composable
    fun MyComposable(input: Type?) {
      input?.let {
        XComposable(input)
      } ?: YComposable()
    }
    My intuition is telling me that the first one is more idiomatic + it seems easier to understand at a glance but I can’t seem to find any references for that (so if you know of any I’d appreciate linking them)
    1️⃣ 5
    s
    a
    • 3
    • 3
  • p

    Peter

    05/06/2025, 11:40 AM
    How can I make
    TextField
    not focusable, but still keep it clickable?
    a
    a
    m
    • 4
    • 9
  • u

    Usman

    05/06/2025, 12:37 PM
    I have a question that is if I use Android jetpack compose Kotlin multiplatform Compose multiplatform & Little but (Ios swiftUI) So the main question is how java developer learn java for backend that,s how I also need to learn kotlin yes or no If yes then what stratge I need to use to learn kotlin If someone say that you don,t need to learn kotlin you just need to learn java with das so how java is helpful in that technology what I use because now 10 months ago I learn all these concepts and technology and I can,t see java I see only kotlin and java is used in kotlin backend like kotlin is java based so If anyone have this kind of experience so tell me what language I need to learn in high level mode like OOP's DSA REPOSITORY DESIGN PATTERN and plz don,t say that you do dsa in swift 😉
    not kotlin but kotlin colored 4
  • t

    Timothy Joseph

    05/06/2025, 1:50 PM
    I'm migrating an app from xml to compose, I have a custom theme the created using compositionLocal, since I don't want to use system UI mode, I'm changing my theme manually following the custom theme... I have some view based UI that can't be replicated in compose so setting the theme manually breaks it by just sticking to the colorOnPrimary for light mode from the themes.xml I was able to do a force update by creating a new context everytime I change the theme and passing it to a context contextThemeWrapper
    Copy code
    val inNightMode = LocalNightMode.current
    val context = LocalContext.current
    val mContext = remember (inNightMode){ context.withForcedNightMode(inNightMode) }
    val ctxThemeWrapper = remember(mContext) {
            ContextThemeWrapper(mContext,R.style.Theme_PROlauncher)
        }
    
    AndroidView(factory = { ctx ->
        TextView(ctxThemeWrapper)
    })
    ,...... so that's fixed too The app supports edge to edge, but I added some margin to the bottom of the composables to make it seem as if it's above the navigation bar and Now I have to set a translucent navigation Bar and change the navigation bar icon to based on the theme mode since that was part of the attributes in the themes.xml, and anytime I set the custom theme mode to light and toggle the nav bar icons based on this, instead of starting at the edge of the screen, the margins I added start from the top of the nav bar and also the transluscent bg becomes completely white
    Copy code
    val insetsController = WindowCompat.getInsetsController(window, window.decorView)
    insetsController.isAppearanceLightNavigationBars = isLightTheme
    the full method
    Copy code
    @Composable
    fun ApplyEdgeToEdge(isLightTheme: Boolean) {
        val view = LocalView.current    val activity = view.context as Activity
    
        SideEffect {
            val window = activity.window
    
            // Ensure edge-to-edge layout
            WindowCompat.setDecorFitsSystemWindows(window, false)
    
            // Transparent system bars
            window.navigationBarColor = Color.Transparent.toArgb()
    
            // Disable nav bar contrast (API 29+)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                window.isNavigationBarContrastEnforced = false
            }
    
            // Optional (legacy translucent fallback)
            @Suppress("DEPRECATION")
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    
            // Control icons
            val insetsController = WindowCompat.getInsetsController(window, window.decorView)
            insetsController.isAppearanceLightNavigationBars = isLightTheme
        }
    }
    is there a way I could fix this???
    🧵 1
  • m

    mattinger

    05/06/2025, 3:48 PM
    Hi all. I'm trying to render a gallery screen as a grid. What i'd like to do is to give each tile a composable, and capture that composable to a bitmap, scale it to a certain size, and render as an image. I've seen this article on doing this, but it renders the composable on screen and saves the picture to a file. What i really want is to just capture the rendering so i can display a preview of it. I've also looked at the Capturable library but it seems to also be geared towards content that's already rendered on screen.
    s
    s
    • 3
    • 5
  • a

    Arsildo Murati

    05/06/2025, 5:24 PM
    https://blog.jetbrains.com/kotlin/2025/05/compose-multiplatform-1-8-0-released-compose-multiplatform-for-ios-is-stable-and-production-ready/
    🚀 26
    🎉 10
    👀 10
    K 8
    ♥️ 6
    🎉 12
    K 17
    c
    g
    t
    • 4
    • 4
  • c

    Cedrick Cooke

    05/06/2025, 11:46 PM
    Is there a way to reliably prevent Compose on Web from making a network request for each-and-every string resource? I’m already providing a
    Cache-Control
    header server-side, but client-side still ends up revalidating the request for each string and receiving a lot of
    304
    responses sequentially.
    e
    • 2
    • 2
  • m

    mattinger

    05/07/2025, 6:51 PM
    Good afternoon all. I'm working in a hybrid xml view / compose environment and we wrote some wrappers for our compose buttons so that they can be used in an xml layout. The one remaining issue we're having is that espresso matchers like
    withText
    do not work because we're not extending TextView. I can write explicit matchers on properties of that wrapper, but i'd like to be able to use the root view and execute any composed based matcher on that. Anyone have any idea if this is possible? Something like:
    Copy code
    onView(
      allOf(
        withId(R.id.button),
        withComposeText(buttonText)
      )
    )
    And someone internally look at the compose tree for that view and execute the text assertion there.
    e
    j
    • 3
    • 9
  • j

    Jonathan

    05/07/2025, 9:06 PM
    Since Compose Multiplatform has gone stable for iOS, does this mean there is support for
    BackHandler
    ?
    c
    • 2
    • 2
  • l

    Lukas Anda

    05/07/2025, 9:47 PM
    Anyone else experiencing really long ios build times when updating to compose multiplatform 1.8.0?
  • l

    Lukasz Kalnik

    05/08/2025, 9:40 AM
    With the update to Compose 2025.04.01 we observe flaky behavior in a screen with two composables inside a Theme:
    Copy code
    override fun onCreate(...) {
        setContent {
            uiState by viewModel.uiState.collectAsStateWithLifecycle()
                
            MyTheme {
                MyScreen(uiState)
                (uiState.overlayState as? ScannedItemOvelayState)?.let { scannedItemOverlayState ->
                    MyOverlay(scannedItemOverlayState)
                }        
            }
        }
    }
    The flakiness is that
    MyOverlay
    is sometimes not hidden even though
    showOverlay
    is null. However, when I wrap those both composables in a
    Box
    ,
    MyOverlay
    is hidden reliably every time.
    • 1
    • 1
  • n

    Nitesh Singh

    05/08/2025, 10:15 AM
    composable( route = Screen.RestaurantMenu.route, // Uses "restaurantMenu/{restaurantId}" arguments = listOf(navArgument("restaurantId") { type = NavType.StringType }) // Define argument type ) { backStackEntry -> // You can retrieve the argument here too if needed directly in Composable, // but ViewModel is preferred for business logic. // val restaurantIdFromArgs = backStackEntry.arguments?.getString("restaurantId") // Pass restaurant name if you have it from a previous screen or fetch it // For simplicity, let's assume you might pass it or fetch it in ViewModel RestaurantMenuScreen( // viewModel is handled by Hilt restaurantName = backStackEntry.arguments?.getString("restaurantName") // Optional: if you also pass name ) } hey there, could you help what do mean of that code .
    🧵 3
  • m

    MarkRS

    05/08/2025, 1:08 PM
    I have an image that I want to render in various colours (according to state). Setting the colour filter on the image with ColorFilter.tint() seems to make no difference at all. How can I change the colour? Unfortunately I can't use multiple images in different colours because I want the actual colour corresponding to a state to be set by the user. The image is remarkably like my icon here, I just want the coloured part to change.
    j
    a
    • 3
    • 11
  • o

    Omico

    05/09/2025, 1:10 AM
    Has anyone use MVI arch, Jetpack Paging in CMP?
    Copy code
    @Immutable
    data class GalleryUiState(
        val galleryImagePagingData: Flow<PagingData<GalleryImage>> = emptyFlow(),
        val eventSink: (GalleryUiEvent) -> Unit = {},
    ) {
        companion object {
            val Empty: GalleryUiState = GalleryUiState()
        }
    }
    Currently, I have to use
    Flow<PagingData<GalleryImage>>
    inside of the UiState, but I don't think this is a good practice. If I use
    PagingData<GalleryImage>
    instead, which cause me unable to use
    collectAsLazyPagingItems()
    in the Composable function. Full project here https://github.com/Omico/picsum I saw Chris circumventing this by using Circuit, but it seems like a better design pattern is needed if we want to achieve it without using Circuit. https://github.com/chrisbanes/tivi/blob/a0c62c2c763c83e3a0ecf79b283224374bb06c4a/u[…]ommonMain/kotlin/app/tivi/home/popular/PopularShowsPresenter.kt
    👀 1
    t
    • 2
    • 3
  • m

    mohamed rejeb

    05/09/2025, 9:01 AM
    Is there any plan to add predefined compose multiplatform navigation and lifecycle dependencies the same as other compose dependencies? It's not part of compose but currently the versions are really coupled to each other and can cause issues.
  • j

    Jonathan

    05/09/2025, 1:14 PM
    Is there a “compose way” to invoke callback passing touch based data from a custom composable? I’m using
    Canvas {}
    to draw a custom graph and I’d like to report the trig values (
    sin
    ,
    cos
    ,
    tan
    ,
    theta
    ) at which the graph was last interacted to calling code. My concern is invoking the callback to often even when the angle hasn’t changed (I do some rounding so tiny changes won’t be reflected). Is this a better use for custom state class to hold the values?
    t
    • 2
    • 33