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

    Dekroo

    06/30/2025, 8:08 PM
    Hi everyone, I'm experiencing an issue where the initial text color in my app isn’t applied correctly - it shows wrong colors at first but changes to the expected black after I minimize and reopen the app. Has anyone encountered this kind of problem before? Any ideas on why this happens and how to fix it?
    Copy code
    @Composable
    fun AppTheme(
        darkTheme: Boolean = isSystemInDarkTheme(),
        dynamicColor: Boolean = true,
        content: @Composable() () -> Unit
    ) {
      val colorScheme = when {
          dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
              val context = LocalContext.current
              if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
          }
    
          darkTheme -> darkScheme
          else -> lightScheme
      }
    
      MaterialTheme(
        colorScheme = colorScheme,
        typography = AppTypography,
        content = content
      )
    }
    --------------- 
    Text(
         text = qrCode,
         modifier = modifier,
         style = MaterialTheme.typography.bodyMedium,
         color = MaterialTheme.colorScheme.onSurface
    )
    b
    • 2
    • 8
  • j

    Jonathan

    06/30/2025, 9:25 PM
    What the recommended way of animating the placement of child
    Composables
    inside of a custom
    Layout {}
    ? I would like to animate the relative positions of child
    Composable
    in my custom Scaffold Composable based the offset of an
    AnchoredDragState
    . Essentially, I would like to slide my nav bar “out of the way” when a sibling
    Composable
    is dragged. I’ve got a POF working using a
    Box
    the
    Modifier.offset { ... }
    on my child
    Composables
    and hardcoded sizes. I would like to be able to wrap this logic up in a custom
    Layout
    and not have to rely on individual offset modifiers and hardcoded sizes. Previously, I tried building this by accessing the offset of a AnchoredDraggableState but dragging became erratic. If anyone has any experience with this, any advice would be appreciated.
    s
    • 2
    • 2
  • d

    Dovydas

    07/01/2025, 6:56 AM
    Hi, I am running into a small issue when using the shared element API with navigation. I want to have a shared background composable between screens. My background is just this:
    Copy code
    Box
      Background (modifier applied to this)
      Content
    When I set the background to be a shared element, it renders in the overlay and above the content during the transition. So I also set
    renderInSharedTransitionScopeOverlay
    for the content, but now it loses it's navigation transitions. Therefore after that I also add
    animateEnterExit
    on the content with the same transition. But that modifier has no context about the difference between pop and push transitions, so I lose my seperate pop transitions. And from there I don't know how to proceed further, my full code is in the thread.
    • 1
    • 1
  • t

    Tim Karagosian

    07/01/2025, 12:43 PM
    Hello all! Old school Android engineer here jumping back into being an engineer and starting a new role soon! I am working on testing my code. In the old Java+XML days about 9 or more years ago I was able to use the UI methods and mock the UI and felt like I could test practically anything. I just struggled a bit trying to get things working for unit tests in my UI Compose classes and I finally was forced to only using the AndroidTest instrument tests. Are there ways of testing my View methods or am I doing it correctly via Instrument testing only and I'm stuck in the past thinking I can do all those tests as Unit Tests? Additionally if I have to have them as instrument tests only, how do I handle the CI/CD for the instrument testing?
    j
    • 2
    • 5
  • r

    Raymond

    07/01/2025, 4:09 PM
    Untitled.cpp
    Untitled.cpp
  • r

    Raymond

    07/01/2025, 4:09 PM
    Hello! Is there a standard way to handle nested scrolling for horizontal RecyclerViews placed inside an Android Fragment that's contained within a compose HorizontalPager? Here's a minimal snippet of code that reproduces the issue:
  • m

    mattinger

    07/01/2025, 4:28 PM
    So, i've been playing with the compose multipreviews, and i wanted to tweak it by creating my own annotations. However, it seems like using the old symbols like
    Devices.TABLET
    is an error, as it's an older form of specifying the device configuration. AS fixes it by inlining the configuration:
    Copy code
    @Preview(device = "spec:width=1280dp,height=800dp,dpi=240")
    I can then add things like
    orientation=portrait
    . This is all well and good, but i'd rather use the built in
    pixel_tablet
    spec and have it rotated to portrait mode. However, i can't figure out if there's a way to do that and then apply landscape mode. The documentation on using these new definitions seems a bit scarce where i'm looking (and the autocomplete only shows
    pixel_5
    in the new type of spec) https://developer.android.com/develop/ui/compose/tooling/previews Anyone have suggestions as to how to do this without a fully custom device specification, and/or any other documentation i might have missed?
  • c

    Colton Idle

    07/02/2025, 12:56 AM
    I'm using navigationBar from m3. Sometimes I will have 4 tabs... sometimes I will have 3 depending on whether the user made a purchase. I have this working, but it looks janky because of how the nav bar icon appears. Is there any way to add some animation to navigationBar when adding an extra tab? My tab code is essentially this from the docs
    s
    s
    • 3
    • 6
  • m

    Michal Klusák

    07/02/2025, 7:29 AM
    Hi. After update to targetSdk 35, WindowInsets.isImeVisible stopped working. It returns true even if keyboard is hidden and not reflects any of keyboard visibility changes. AndroidMainfest:
    Copy code
    android:windowSoftInputMode="adjustResize"
    Activity xml:
    Copy code
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="<http://schemas.android.com/apk/res/android>"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="false">
    
        <FrameLayout
            android:id="@+id/root_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="false" />
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    Versions: compose = 1.7.5
    z
    • 2
    • 3
  • j

    Jirka Hutárek

    07/02/2025, 1:51 PM
    Hi! When I have more than one modal thing shown on the screen (let's say a M3 modal bottom sheet and a dialog), is it possible to specify which one should be at the top of the other? It seems like only the order of their appearance matters:
    Copy code
    import android.os.Bundle
    import androidx.activity.ComponentActivity
    import androidx.activity.compose.setContent
    import androidx.compose.foundation.background
    import androidx.compose.foundation.layout.Box
    import androidx.compose.foundation.layout.Column
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.foundation.layout.fillMaxWidth
    import androidx.compose.foundation.layout.height
    import androidx.compose.foundation.layout.size
    import androidx.compose.material3.Button
    import androidx.compose.material3.ModalBottomSheet
    import androidx.compose.material3.Text
    import androidx.compose.runtime.getValue
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.remember
    import androidx.compose.runtime.rememberCoroutineScope
    import androidx.compose.runtime.setValue
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.graphics.Color
    import androidx.compose.ui.unit.dp
    import androidx.compose.ui.window.Dialog
    import kotlinx.coroutines.delay
    import kotlinx.coroutines.launch
    
    internal class SampleActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            setContent {
                val coroutineScope = rememberCoroutineScope()
                var sheetVisible by remember { mutableStateOf(false) }
                var dialogVisible by remember { mutableStateOf(false) }
    
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                ) {
                    Button(
                        onClick = {
                            coroutineScope.launch {
                                sheetVisible = true
                                delay(500)
                                dialogVisible = true
                            }
                        }
                    ) {
                        Text("Sheet -> Dialog")
                    }
                    Button(
                        onClick = {
                            coroutineScope.launch {
                                dialogVisible = true
                                delay(500)
                                sheetVisible = true
                            }
                        }
                    ) {
                        Text("Dialog -> Sheet")
                    }
                }
    
                if (sheetVisible) {
                    ModalBottomSheet(
                        onDismissRequest = { sheetVisible = false },
                    ) {
                        Box(
                            modifier = Modifier
                                .background(Color.Yellow)
                                .fillMaxWidth()
                                .height(320.dp)
                        )
                    }
                }
    
                if (dialogVisible) {
                    Dialog(
                        onDismissRequest = { dialogVisible = false },
                    ) {
                        Box(
                            modifier = Modifier
                                .background(Color.Cyan)
                                .size(320.dp, 400.dp)
                        )
                    }
                }
            }
        }
    }
    No matter if I set z-indices on various things, put the modals in boxes, etc., the thing that gets invoked last is the thing that's drawn on top. Is there a way to say have the dialog always on top, no matter if the bottom sheet appears before or after it (except for putting the dialog inside the bottom sheet but that is not my use case)? 🙏
    🧵 9
  • u

    אליהו הדס

    07/03/2025, 7:31 AM
    Hi, is navigation 3 compatible with cmp?
    🚫 2
  • z

    Zoltan Demant

    07/03/2025, 7:37 AM
    I have this class, and for the most part I just do
    Checkable(x) { .. }
    and that works great. When I instead have
    if(x) Checkable(true) { .. } else Checkable(false) { .. }
    then the Switch composable differs between the two and jumps between the states instead of animating. I think I know why - the context in which the switch is rendered differs, both checked & the lambda differs - but how can I fix that?
    Copy code
    data class Checkable(
        val checked: Boolean,
        val enabled: Boolean = true,
        val onCheckedChanged: (Boolean) -> Unit,
    ) : SettingsAction {
        override val onClick = {
            onCheckedChanged(!checked)
        }
    
        @Composable
        override fun RowScope.Render() {
            Switch(
                checked = checked,
                enabled = enabled,
                onCheckedChanged = onCheckedChanged,
            )
        }
    }
    d
    • 2
    • 8
  • t

    Tower Guidev2

    07/03/2025, 8:57 AM
    Hi, is the following possible i have an android fragment that displays a 100% Compose UI i wish to emmbed this in an xml layout to reuse the Compose Ui from my legacy xml layout i have tried using both a
    androidx.compose.ui.platform.ComposeView
    and
    androidx.fragment.app.FragmentContainerView
    niether of these approaches work How do i show a compose fragment from within an xml layout?
  • r

    Robert Levonyan

    07/03/2025, 10:04 AM
    A question to JetBrains team: do you have a plan when
    dataarg
    classes will be available?
  • p

    Pablo

    07/03/2025, 2:54 PM
    Having a uistate with a lot of variables, I have a screen where I do this:
    Copy code
    val uiState by vm.uiState.collectAsStateWithLifecycle()
    and inside that screen I have a composable which iterates one list of elements contained on that uistate:
    Copy code
    ListPane(items = uiState.itemsMap,
    I want a recomposition if the user changes the order of the map (I have a button for that), but it's a map, and unfortunately if you change the map order, JVM will consider the same instance of the previous unordered map, so recomposition is not dispatched. But I noticed that if I have a different variable in the uistate, for example, a count which is increased each time the map is ordered... then, suddenly the screen starts recomposing. How it's possible? if I am not reading that count value anywhere, is just stored in the uistate, but is not used or accesed.
    s
    c
    • 3
    • 18
  • a

    Ahmed Elkhodery

    07/03/2025, 5:52 PM
    While running
    :wasmBrowserDevelopmentRun
    to develop on the wasmJS target i'm getting this error:
    e: java.lang.IllegalStateException: IC internal error: can not find library org.jetbrains.androidx.graphics:graphics-shapes
    i tried to bump compose version to
    1.9.0-alpha02
    but still didn't solve i'm on kotlin
    2.1.21
    • 1
    • 2
  • p

    Pranathi

    07/04/2025, 6:36 AM
    hey all, I am working on a compose multiplatform project I want for a specific screen to not get rotated and remain same no matter what the orientation is. Does anyone have leads related to this?
  • g

    Guyaume Tremblay

    07/04/2025, 1:02 PM
    Hi all! I'm migrating an Android compose and swiftui ios app to compose multiplatform and I'm facing an issue (had a workaround on Android but I want to know if someone found a better solution since). I have a screen which is basically a webview. This screen need to be pre-loaded and can be access everywhere in the app (so, should be a nav destination). But... the webview reload each time I navigate to it! I used the
    rememberSaveableWebViewState
    from Accompanist but without success. Also, tried using MovableContentOf but had a weird issue where it was trying to compose the webview at both place and crash (doesn't remember well, should probably try again) My final workaround was to place it in a box next to the navhost and flipping the alpha... Do you have something better ?
  • b

    Badran

    07/04/2025, 1:17 PM
    Hi all, I am trying to implement a border around focused items, I have tried several approaches but most of them makes my component jump a bit and the other solution makes the border overlaps a bit with the content of the item and block them like checkboxes. Is there any ideas where can this be achieved in an easier / more generic way in compose
    ✅ 1
    k
    s
    a
    • 4
    • 9
  • r

    Reprator

    07/04/2025, 6:47 PM
    Hi all, I am trying to understand the recomposition of unstable lambda,
    data class LambdaUnStableSample1ContextWrapper(val context: Context) //Unstable due to usage of context
    @Composable
    private fun LambdaUnStableSample1Outer(
    onClick: () -> Unit
    ) {
    println("RecompositionLambdaSampleList LambdaUnStableSample 3: Outer")
    Column(
    modifier = Modifier
    .border(2.dp, getRandomColor())
    .padding(10.dp)
    ) {
    Button(onClick = onClick) {
    Text(text = "Click")
    }
    }
    }
    @Composable
    private fun LambdaUnStableSample1() {
    var counter by remember {
    mutableIntStateOf(0)
    }
    val contextWrapper = LambdaUnStableSample1ContextWrapper(LocalContext.current)
    println("RecompositionLambdaSampleList LambdaUnStableSample 1: root")
    Column {
    println("RecompositionLambdaSampleList LambdaUnStableSample 2: Column")
    LambdaUnStableSample1Outer {
    println("RecompositionLambdaSampleList LambdaUnStableSample 4: Outer")
    counter++
    contextWrapper.context
    }
    }
    }
    the output is:
    RecompositionLambdaSampleList LambdaUnStableSample 4: Outer
    But the output should be  or i am expecting is as follows:
    RecompositionLambdaSampleList LambdaUnStableSample 4: Outer
    RecompositionLambdaSampleList LambdaUnStableSample 1: root
    RecompositionLambdaSampleList LambdaUnStableSample 2: Column
    RecompositionLambdaSampleList LambdaUnStableSample 3: Outer
    As the lambda is unstable due to usage of contextWrapper.context in lambda body,
    So can anyone help me to understand, why it is not printing the all, that i am expecting Or please provide me with a simple example were the composable recompose due to unstable lambda, without any viewmodel
    🧵 3
  • i

    Idris Ocasio

    07/04/2025, 10:28 PM
    I'm trying to build a signup screen with compose multiplatform. The first screen is a landing page and then signup flow slides in from the right. If the user presses the back button, they exit from the right. I have two questions. Is it possible to create a koin viewmodel that's only scoped for the lifetime of the signup flow and once the user abandons it, the viewmodel doesn't exist. And the second question, if I'm showing screen B, it comes in from the right, but screen A does its exit animation too. I only want screen A to 'exit' if the user actually removes it from the backstack. Not if a new screen is just showing. Is this possible with compose navigation?
  • d

    Dave Leeds

    07/06/2025, 7:17 PM
    Hi all - Working on a CMP app with type-safe nav, using 2.9.0-beta03. I noticed when I use a serializable value class, like this...
    Copy code
    @Serializable
    @JvmInline
    value class Id(val value: String)
    ... as part of a route class like this ...
    Copy code
    @Serializable
    data class Document(val id: Id)
    Then I get an error when trying to navigate with it.
    Copy code
    DocumentListScreen(onDocumentClicked = { id -> nav.navigate(Document(id)) })
    Here's what the error looks like:
    Copy code
    Route Document could not find any NavType for argument id of type Id - typeMap received was {}
    I've worked around this by unwrapping the value.
    Copy code
    DocumentListScreen(onDocumentClicked = { id -> nav.navigate(Document(id.value)) })
    And then reinstantiating the
    Id
    value class on the other side. But I'm wondering whether I'm doing things right. Is there a more appropriate way to make this work? I'd love to keep using value classes for things like this if possible.
    l
    • 2
    • 2
  • u

    谢朋刚

    07/07/2025, 9:28 AM
    Hello everyone, I’d like to ask about the best practices for reusing Compose Modifiers. What are the differences between
    @Composable Modifier
    ,
    composed
    factory, and
    Modifier Node
    ? I still don’t quite understand the distinctions among these three, and even feel that their final effects are the same.
    c
    • 2
    • 3
  • j

    Jordi Saumell

    07/07/2025, 12:14 PM
    Hi all! I have a question about accessibility (toggleable) that should be simple but I can't find the solution: I have a Row with a text and a switch, and the whole row is clickable and controls the switch state. For accessibility I set
    .toggleable(isSelected, Role.switch, onValueChange)
    . The problem is the reading order: it first reads "on/off", then the label text, then "switch", and finally the click action. I don't see how to change the order: my understanding is that it should read as label - state - "switch" - action. I have tried many things, even setting it manually (which I don't like, as I want to use the standard state description instead of providing a custom one), and it keeps reading the state first:
    Copy code
    Modifier.clearAndSetSemantics {
                            contentDescription = text
                            this.role = Role.Switch
                            this.onClick = onValueChange
                            stateDescription = if (selected) {
                                "On"
                            } else {
                                "Off"
                            }
                        }
  • m

    mattinger

    07/07/2025, 2:46 PM
    Hi all. I'll preface this by saying i'm not really sure if this fits into compose, or even kotlin as a whole, but it's an issue that i'm encountering because we're using compose mixed with other native view components. Basically, what we're trying to do is create our own "toast" type component, but with it's own visuals and behavior (it doesn't follow the same behavior and visuals as toast does so it doesn't make sense to try to fit it into the toast system). As you can see in the image below it overlays the content, but i want to make sure there's a way to guarantee that all the content under it is able to seen or interacted with. My thoughts immediately went to insets and seeing if there was a way I could read an inset based on the current height of the toast, and apply internal bottom padding to the container behind the component. I'm wondering if there's any good way to create my own type of insets accessible from both native views and compose, and recognize when the toast changes height and adjust accordingly. The documentation suggests I can't create a new WindowInsets.Type but i'm wondering if there's some other approach
  • u

    谢朋刚

    07/08/2025, 2:25 AM
    If I want to ensure the following code is applied within BoxScope:
    @Composable fun Modifier.floatAction(): Modifier = this.align(Alignment.BottomEnd)
    Does it need to be changed to:
    @Composable fun BoxScope.floatAction(): Modifier = Modifier.align(Alignment.BottomEnd) // this is wrong
    Or use Kotlin's context parameters feature.
    j
    • 2
    • 1
  • s

    Sangeet

    07/08/2025, 6:28 AM
    Hi, There was some suggestion to use
    collectAsStateWithLifecycle
    on consumer side and
    stateIn
    in producer side to restrict view getting updates https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3 https://medium.com/androiddevelopers/things-to-know-about-flows-sharein-and-statein-operators-20e6ccb2bc74
    Copy code
    .stateIn(
                viewModelScope,
                SharingStarted.WhileSubscribed(5000L),
                null
            )
    Also there was some suggestion to use it to fetch initial data for a screen rather than using
    init
    or
    LaunchedEffect(Unit)
    as it have its own issue. One problem which I found was the data will be re-fetched if screen is kept in background for more than 5s which is kind of making bad UX if we don't hold data in repo layer. Are there any better approach for fetching initial data from compose screens ?
    d
    • 2
    • 1
  • s

    Slackbot

    07/08/2025, 10:50 AM
    This message was deleted.
    Screen_recording_20250708_124127.mp4
    m
    • 2
    • 2
  • t

    Tower Guidev2

    07/08/2025, 2:39 PM
    hi, i have just upgraded my android application to use kotlin
    2.2.0
    and compose bom
    2025.06.01
    my application has developed an issue where single items within a LazyColumn are not being recomposed e.g. when selected or selection is toggled, basically any list item that is affected by any user interaction now does not recompose to reflect the user interaction. when i downgrade kotlin to
    2.1.10
    the issue does not exist. why is this?
    a
    • 2
    • 1
  • t

    Tapan Desai

    07/08/2025, 4:08 PM
    Hi, I am exploring
    Navigation3
    library right now. I have come across a scenario where we need to scope a
    ViewModel
    to the previous screen Current we are using compose-destinations which is built on top of Jetpack Navigation library We scope a
    ViewModel
    to the previous destination like this. Can this is be achieved in
    Navigation3
    ?
    Copy code
    @Composable
    @Destination(style = DestinationStyleBottomSheet::class)
    fun ColumnScope.SalesStaffBottomSheet(
        navigator: DestinationsNavigator,
        navBackStackEntry: NavBackStackEntry,
        navController: NavController,
        result: ResultBackNavigator<SalesStaffDetails>,
    ) {
        val backStack = remember(navBackStackEntry) {
            navController.getBackStackEntry(AnalyticsMobileDestination.route)
        }
        val viewModel = hiltViewModel<AnalyticsViewModel>(backStack)
    
        val uiState by viewModel.analyticsUiState.collectAsStateWithLifecycle()
        SalesStaffDialogBottomSheet(
            uiState = uiState,
            onSalesStaffClick = { result.navigateBack(it) },
            onCloseClick = { navigator.popBackStack() }
        )
    }