https://kotlinlang.org logo
Docs
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
compose
  • e

    elye

    02/27/2022, 11:09 AM
    Made a Perlin Noise interpolator for Jetpack Compose Animation.
    👍 9
    🆒 5
    👍🏼 2
    1 reply · 1 participant
  • d

    dimsuz

    02/27/2022, 11:17 AM
    When using navigation component is it ok to use
    navControler.graph.addAll(otherGraph)
    /`navController.graph.addDestination()` after navigation has started? For example I want to dynamically decide, based on some user choice, that I want to add a whole bunch of new destinations. Will this work OK (+with composables in the graph)? Or is navigation component designed only so that whole graph must be constructed at once on the start?
    a
    2 replies · 2 participants
  • c

    Colton Idle

    02/27/2022, 11:24 PM
    I'm using a
    mutableStateListOf<T>
    but when I call clear() and then addAll() to it, it seems like compose tries to be "smart" and apply only the changes between the two lists. Is there a way to "opt out" of that behavior? So Im looking to go from this:
    state.list.clear()
    state.list.addAll(networkResult.newItems)
    to something like this (completely made up api)
    state.list.clear().commitTransactionAndWait()
    state.list.addAll(networkResult.newItems).commitTransactionAndWait()
    j
    e
    +1
    20 replies · 4 participants
  • y

    YASAN

    02/28/2022, 9:19 AM
    I have a
    Column
    inside a
    Row
    . The
    Column
    has a
    Modifier.weight(1f)
    inside if which fills the UI with a blank space. Once I add
    Modifier.requiredHeight(IntrinsicSize.Min)
    to the
    Row
    , the weight modifier wont work anymore (it will have width of 0. My
    IntrinsicSize.Min
    is applied to height only, why is it affecting the width of my items? Ill post some code in the thread
    2 replies · 1 participant
  • s

    Sean Proctor

    02/28/2022, 12:28 PM
    the trailing part of a ListItem with three lines doesn't seem to follow the spec (or look nice). The trailing part is put at the top of the ListItem. The spec says it should have 16 dp padding. Adding padding has no effect. Is there a workaround for this that doesn't involve writing my own ListItem?
    1 reply · 1 participant
  • a

    aoriani

    02/28/2022, 2:32 PM
    https://developer.android.com/jetpack/compose/interop/compose-in-existing-arch#viewmodel says that ViewModels will still be tied to the lifecycle of the activity or fragment in which they were created. Is there any way to tie it to the "lifecycle of the composition" or should I use some DisposableEffects to reset view models' state?
    c
    s
    +1
    8 replies · 4 participants
  • m

    martinsumera

    02/28/2022, 2:44 PM
    Isn't there a way how to predefine multiple preview annotations and apply them on the preview composable? It would be much easier to to use something like
    @MyCustomPreviews("component name")
    which be equivalent of the following code
    @Preview(name = "ProgressButtonPreview")
    @Preview(name = "ProgressButtonPreview - night", uiMode = Configuration.UI_MODE_NIGHT_YES)
    @Preview(name = "ProgressButtonPreview - scaled font", fontScale = 3f)
    @Preview(name = "ProgressButtonPreview - en", locale = en)
    ...
    @Preview(name = "ProgressButtonPreview - api 26", apiLevel = 31)
    e
    c
    9 replies · 3 participants
  • e

    Enrico Saggiorato

    02/28/2022, 6:23 PM
    Hi, I'm trying to add password visibility toggle to a TextField but I cannot find Visibility icon. Do I have to install some extra libraries? I'm trying to use Icons.Filled.Visibility but Android Studio shows an error and is not able to import anything
    s
    m
    +4
    12 replies · 7 participants
  • b

    brabo-hi

    03/01/2022, 4:11 AM
    Hi all, i have a text with maxLines 1, how to get overflow Ellipsis but for the first characters left instead of the the last characters right eg.
    ...lo world!
    s
    s
    2 replies · 3 participants
  • s

    Siyamed

    03/01/2022, 10:53 AM
    FYI: includeFontPadding & Compose https://issuetracker.google.com/issues/171394808
    😍 13
    💥 2
    🎉 8
    c
    c
    8 replies · 3 participants
  • h

    hfhbd

    03/01/2022, 11:21 AM
    Not a really compose question, but I think,
    ActivityResultContracts.TakePicture()
    should return the file to match Compose declarative style. Currently, you have to create the file first, and keep a reference to it to use it after the camera intent finished successfully. Creating a
    TakePicturePlus()
    returning
    Uri?
    instead does not work, because the
    TakePicture
    result intent is almost empty.
    g
    i
    9 replies · 3 participants
  • k

    Kata

    03/01/2022, 2:13 PM
    Is there a way to set horizontal and vertical offset for
    BadgedBox
    , like it was possible for
    BadgeDrawable
    ?
    c
    2 replies · 2 participants
  • o

    Oleg Tretiakov

    03/01/2022, 2:18 PM
    Hey everyone! Has anyone ever faced this issue while migrating to the latest compose and kotlin? My current compose version is 1.1.0-beta03 This error pops up when i try to update to 1.1.1 and 1.6.10 of Kotlin
    s
    3 replies · 2 participants
  • t

    theapache64

    03/01/2022, 3:07 PM
    The below code will print
    B
    null?.let {
        println("A")
    } ?: println("B")
    but the below code doesn’t render
    B
    null?.let {
        Text(text = "A")
    } ?: Text(text = "B")
    Why? 🤔
    f
    a
    +2
    14 replies · 5 participants
  • m

    Marcin Wisniowski

    03/02/2022, 2:21 AM
    What's the non-lazy equivalent of
    LazyVerticalGrid
    ?
    f
    2 replies · 2 participants
  • a

    Abhishek Dewan

    03/02/2022, 6:39 AM
    I have a navigation back stack in my app that can be in one of two states: 1. Splash -> Home 2. Splash -> Landing -> Sign_In -> Home The following is the navigation code that navigates to the HomeScreen
    override fun navigateToHome() {
        navController.navigate(RootScreen.Home.route) {
            val popUpRoute = navController.currentBackStackEntry?.destination?.route ?: ""
            popUpTo(popUpRoute) {
                inclusive = true
            }
        }
    }
    I would like to make sure that I can clear the back stack completely and then navigate to home. The way I understand navigation, calling popUpTo(currentScreenOnBackStack) should clear all the backstack before we navigate to Home and should account for both scenarios above. I’m sure I’m misunderstanding something obvious. Would appreciate if someone could point it out for me.
    c
    3 replies · 2 participants
  • i

    ildar.i [Android]

    03/02/2022, 8:16 AM
    Compose animation has a slideInVertically transition. It animates from the top. Is there a way to animate it from the bottom?
    b
    2 replies · 2 participants
  • w

    wintersoldier

    03/02/2022, 8:21 AM
    Whats the best way to do State Management for compose , do anyone have some best approaches reads or sample I can take a look. I have tried state hoisting in viewmodel for `InputField`but it was bit messy since there was lot of state for error , label , placeholder and data . Any suggestions will be helpful
    i
    8 replies · 2 participants
  • a

    Ankit Dubey

    03/02/2022, 11:21 AM
    Can we restrict user to enter only alphanumeric chars in BasicTextField. E.g. we can do this in xml as follows ->
    android:digits="abcdefghijklmnopqrstuvwxyz1234567890 "
    f
    3 replies · 2 participants
  • l

    Luka

    03/02/2022, 2:12 PM
    Hi. I have 2 screens with videoview inside and i make transition between them using accompanist-navigation-animation lib. Transition between 2 compose “screens” is slow, i think it might be related to how i start videos, but i cant figure it out. Also when transition from first to second screen is made recomposition is run many times. Can somebody with more knowledge in compose please take a look how i handle video playback please. Thank you
    :thread-please: 1
    f
    5 replies · 2 participants
  • n

    Nick

    03/02/2022, 2:36 PM
    How do I determine if this dropdown is overlapping the keyboard?
    👀 2
    1 reply · 1 participant
  • t

    Tim Malseed

    03/02/2022, 2:36 PM
    With Compose Navigation, let’s say you’re using BottomNavigation and you want a particular tab to remain selected as you navigate deeper.. I’ve seen something like this:
    val selected = currentDestination
        ?.hierarchy
        ?.any { it.route == bottomNavItem.destination.route } == true
    1. Is the idea that you have to leverage nested graphs in order for this to work? I’m sure this probably makes sense (because how else does Compose know that a particular destination belongs to the same hierarchy) So, assuming that is the case 2. If you have a screen that is accessible from two different Bottom Navigation roots.. You’d have to declare that route twice (once in each graph)? If that’s how it works, cool. Just want to make sure I’m thinking about this the right way
    a
    i
    6 replies · 3 participants
  • m

    Marcin Wisniowski

    03/02/2022, 5:17 PM
    Is there a way to disable gestures on a Composable? I have a Composable that handles gestures I don't want (should just be a static read-only component). I tried this: https://stackoverflow.com/a/69146178, but my Composable is inside a scrolling Column, and it prevents scrolling the parent Column too, if you try to drag by my Composable.
    c
    z
    +1
    8 replies · 4 participants
  • s

    ste

    03/02/2022, 6:05 PM
    I was wondering why
    Modifier.swipeable
    is part of
    compose-material
    , is there a specific reason? (I mean, it may be useful to non material design users - it also doesn't depend on any MD specific item, of course)
    e
    j
    +3
    10 replies · 6 participants
  • m

    mattinger

    03/02/2022, 11:18 PM
    Does anyone know if kotlin 1.6 has finally stabilized the compiler api so that future versions of compose beyond 1.1.x won’t be so tightly coupled to the kotlin version?
    🇳🇴 3
    e
    j
    4 replies · 3 participants
  • c

    Chris Johnson

    03/03/2022, 12:07 AM
    Compose internally is saying there's something wrong with how I'm using the focus api. Code in 🧵
    c
    5 replies · 2 participants
  • s

    smallshen

    03/03/2022, 12:58 AM
    What is the best way to handle states that update more than 100 times per second?
    k
    6 replies · 2 participants
  • a

    Andy Himberger

    03/03/2022, 3:34 AM
    Should InteractionSource.Hover enter/exit work when using a mouse or trackpad? (or something else work for mouseover visuals) With my Samsung tablet's trackpad I don't see any hover visuals in compose like I do with Views. I debugged it a little bit and found in AndroidComposeView.android.kt all the trackpad input events are ignored because they are hitting this condition:
    if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN) &&
        event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER
    ) {
        // Accessibility touch exploration
        return accessibilityDelegate.dispatchHoverEvent(event)
    }
    Keyboard navigation visuals work fine with the samsung keyboard, its just the trackpad thats not working
    1 reply · 1 participant
  • s

    sunnat629

    03/03/2022, 6:55 AM
    Hey everyone, I am working in a projects where I am planning to implement Navigation with Bottom bar.
    implementation "androidx.navigation:navigation-compose:2.4.1"
    
    compose version, I tried both 1.1.0 and 1.2.0-alpha04
    I am trying to use this and where I create and add the bottomBar , I got Skipped * frames! The application may be doing too much work on its main thread* without adding any view. my code snaps -
    @Composable
    fun BottomNavigationBar(navController: NavHostController) {
        BottomNavigation(
            backgroundColor = AppColors.BottomNav,
        ) {
            val navBackStackEntry by navController.currentBackStackEntryAsState()
            val currentDestination = navBackStackEntry?.destination
            items.forEach { screen ->
                BottomNavigationItem(
                    icon = {
                        Icon(
                            painterResource(screen.drawableResId),
                            tint = AppColors.secondary,
                            contentDescription = screen.route
                        )
                    },
                    label = { Text(stringResource(screen.resourceId)) },
                    selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
                    onClick = {}
                )
            }
        }
    }
    @ExperimentalMaterialApi
    @ExperimentalFoundationApi
    @Composable
    fun SportWorldUi() {
        val navController = rememberNavController()
        Scaffold(
            topBar = { TopBar(navController) },
            bottomBar = { BottomNavigationBar(navController) },
    //        backgroundColor = Color.Transparent,
            modifier = Modifier.fillMaxSize()
        ) { innerPadding -> }
    If I remove
    bottomBar = { BottomNavigationBar(navController) },
    , it works fine. Where is the issue here? Thanks
    🧵 1
    e
    2 replies · 2 participants
  • z

    ziv kesten

    03/03/2022, 9:46 AM
    I am writing an audio playing component, i have a mutableStateOf the track progress every 100 millis, however, as long as that state is updated i cannot tap the play\pause button that is getting re-rendered every 100 milli, how can i prevent the left square from getting rendered on every track progress mutable state change? all the mutable states are held in a viewModel class, that is passed to the audio record composable.
    t
    m
    64 replies · 3 participants
Powered by Linen
Title
z

ziv kesten

03/03/2022, 9:46 AM
I am writing an audio playing component, i have a mutableStateOf the track progress every 100 millis, however, as long as that state is updated i cannot tap the play\pause button that is getting re-rendered every 100 milli, how can i prevent the left square from getting rendered on every track progress mutable state change? all the mutable states are held in a viewModel class, that is passed to the audio record composable.
t

Tim Malseed

03/03/2022, 10:29 AM
Rather than screenshots, it can be helpful to post code blocks,
like this
Which makes it a bit easier for us to read your code. Can you show us where
trackProgress
is referenced? I can see the slider, but I can’t see why the Card would recompose, because I can’t see what code surrounds your
Card
z

ziv kesten

03/03/2022, 10:35 AM
So the way it is built is basically like this:
@Composable
fun AudioTrackView(viewModel: VoiceRecordingViewModel){
    Row(...) {
        PlayPauseButton() { viewModel.clickAction() }
        Slider(
                value = viewModel.trackProgress,
                valueRange = 0f..duration,
                modifier = Modifier
                   .weight(1f)
                   .fillMaxWidth()
                onValueChange = { newValue ->
                    viewModel.goToTrackPosition(newValue)
                },
             )
        Text(...)
        TrashIcon()
    }
}
trackProgress
which is streamed from the view model is given as the value of the slider
t

Tim Malseed

03/03/2022, 10:38 AM
OK. I’m trying to understand what could be causing recomposition of your
AudioTrackView
here. I don’t see why
viewModel.trackProgress
would cause this
Maybe we need to see the code surrounding
AudioTrackView
?
Could it be some side-effect of
viewModel.goToTrackPosition()
?
👀 1
z

ziv kesten

03/03/2022, 10:39 AM
hmmm, maybe... checking....
Nope, removing that makes not difference
t

Tim Malseed

03/03/2022, 10:42 AM
OK. Can you show us the parent code of
AudioTrackView
?
z

ziv kesten

03/03/2022, 10:42 AM
I will try and summerzie it, one moment....
fun VoiceRecordInput(viewModel: VoiceRecordingViewModel) {
    Column(...)
    {
        Text(...)
        Text(...)
        LaunchedEffect(viewModel) {
            snapshotFlow {
                viewModel.items.firstOrNull { it.state.isIdle && !it.state.targetState }
            }.collect {
                if (it != null) {
                    viewModel.cleanInvisibleItems()
                }
            }
        }
        LazyColumn(
            content = {
                items(
                    items = viewModel.items,
                    itemContent = { item ->
                        AudioTrackView(viewModel, item.audioTrack)
                    }
                )
            }
        )
        Box(...)
        Text(...)
        Button(...)
    }
}
Removing the LaunchedEffect was the first suspect but removing it does not solve the problem
t

Tim Malseed

03/03/2022, 10:48 AM
OK. It’s not immediately clear to me what the cause is. But, to help you diagnose the issue, it’s worth figuring out where recomposition is happening. Is it just the AudioCard, or could it be the VoiceRecordingInput composable, or even the Composable above that, that is being re-composed every x milliseconds?
You can use logcat for this, rather than creating an animating square. Let me find a snippet..
See here: https://github.com/chrisbanes/tivi/blob/404cfe91311d5feb1968f53676179b6a1e9f6abf/common-ui-compose/src/main/java/app/tivi/common/compose/Debug.kt
👀 1
If you add that to your code, and then add
LogCompositions
to your composables, with a different tag for each one, you can narrow down where your excessive recomposition is coming from.
Once you know that, we can then try to narrow it down a bit further
z

ziv kesten

03/03/2022, 10:51 AM
Great! thank you!
The recomposition occurs inside the
PlayPauseButton() { viewModel.clickAction() }
that contains an
AnimatedVisibility
component, i am still investigating but appreciate the help, i hep post my findings here.
t

Tim Malseed

03/03/2022, 11:22 AM
Maybe it’s just recomposing as the ripple animates? (Just a guess, no idea)
It could be that the recomposition isn’t actually the cause of your problem. You said that you can’t tap the play/pause button?
I’m totally guessing now but, I don’t think you’re meant to pass
MutableInteractionSource()
, but instead use
remember { MutableInteractionSource() }
Not sure if that could be the cause of the problem?
z

ziv kesten

03/03/2022, 11:26 AM
I had that thought too as soon as you called the ripple thing but no... 😂
Also, if i place a plain button there it has ripple by default but has no problem, i think it has to do with the
AnimatedVisibility
t

Tim Malseed

03/03/2022, 11:30 AM
Where is the animated visibility? I don’t see it in the code blocks you posted above?
z

ziv kesten

03/03/2022, 11:34 AM
No, there is alot of code so i tried to post only relevant code as much as possible
@ExperimentalAnimationApi
@Composable
private fun AnimatedVisibilityWrapper(
    modifier: Modifier,
    visible: Boolean,
    rotation: Float,
    onClick: () -> Unit,
    content: @Composable () -> Unit
) {
    LogCompositions(tag = "AnimatedVisibilityWrapper")
    AnimatedVisibility(
        visible = visible,
        enter = fadeIn(
            animationSpec = tween(delayMillis = 50, durationMillis = 300, easing = FastOutLinearInEasing)
        ),
        exit = fadeOut(
            animationSpec = tween(delayMillis = 50, durationMillis = 300, easing = FastOutLinearInEasing)
        )
    ) {
        Card(
            backgroundColor = Color(255, Random.nextInt(0, 255), Random.nextInt(0, 255), Random.nextInt(0, 255)),
            elevation = 0.dp,
            modifier = modifier.then(
                Modifier
                    .fillMaxSize()
                    .graphicsLayer { rotationZ = rotation }
                    .clickable(
                        interactionSource = MutableInteractionSource(),
                        indication = rememberRipple(
                            radius = 20.dp,
                            bounded = false
                        )
                    ) {
                        onClick()
                    },
            )
        ) { content() }
    }
}
Used like this
AnimatedVisibilityWrapper(
                    modifier = Modifier.align(Center),
                    visible = !isPlaying,
                    rotation = animateFloatAsState(targetValue = if (isPlaying) 180f else 0f).value,
                    onClick = { viewModel.playClicked(audioTrack.id) }
                ) {
                    Icon(
                        painterResource(id = R.drawable.ic_play),
                        modifier = Modifier.align(Center),
                        contentDescription = "Localized description",
                        tint = colorResource(id = R.color.lemonade_pink)
                    )
                }
isPlaying
is
val isPlaying = viewModel.playing(audioTrack.id)
t

Tim Malseed

03/03/2022, 11:41 AM
i tried to post only relevant code as much as possible
Yes, fair enough haha
So, it’s kind of expected that recomposition is going to occur a lot then, since an animation is occurring
And the animation begins after you press play?
z

ziv kesten

03/03/2022, 11:42 AM
exactly, the pause icon animates away as the play icon animates in
This has to be it
will update
t

Tim Malseed

03/03/2022, 11:46 AM
Hmm.. Ok. It’s a bit confusing, I know you have a lot of code, but with every step you seem to talk about a new piece of code that I haven’t seen yet 😅
So, it sounds like you have more than one of these AnimatedVisibilityWrappers? One that wraps a play button, and one that wraps a pause button?
z

ziv kesten

03/03/2022, 11:47 AM
Yea i thought that the answer would be something obvious i havnet seen.
Yea more then one, this is not a question for this chat then
I appreciate you help alot.
t

Tim Malseed

03/03/2022, 11:48 AM
It might be something obvious yet, but we can’t see enough code.
Like it would be good to see both the buttons, and the parameters they depend on, and for you to mention which button you can’t press and under what conditions
But yeah, if you don’t feel comfortable sharing that code, no problem
z

ziv kesten

03/03/2022, 11:49 AM
If this still boggles me by next week i will post the whole code on some gist and upload here.
You gave me valubale tools though, thank you
t

Tim Malseed

03/03/2022, 11:50 AM
Don’t be afraid to post a ton of code in this thread, I doubt anyone really minds.. it’s a thread so they only see it if they want to
z

ziv kesten

03/03/2022, 11:51 AM
I think it would just be alot more readbale as a gist on github or something
slack does not show vast amounts of code nicely
t

Tim Malseed

03/03/2022, 11:52 AM
Paste away my friend. We’ll manage, that’s what code blocks are for!
z

ziv kesten

03/03/2022, 11:53 AM
but now it's all meesed up from my experiments, and i must also move on to other tasks, i promise i will post a solution or the full code here eventually.
🙌 1
*Update Extracting the Slider out to a private function prevents the AnimatedVisibility from recomposing I am not sure why. Here is the full code https://gist.github.com/zivkesten/c985971e61fd9fb98e884dc067cac1c1
m

myanmarking

03/03/2022, 3:01 PM
when you click play/pause, does the viewmodel method gets called ?
z

ziv kesten

03/03/2022, 3:03 PM
There is a viewModel method that is called on playPause, but it does not trigger the trackProgress state, which is what causing the recomposition. But I want to know, why did you ask?.
m

myanmarking

03/03/2022, 3:05 PM
so that progress is animating, and the square that is blinking is the clickable component, that will cause it to pause/play right ?
oh i was looking to the first screen. The component is the last one ok. You are saying you cannot click the play/pause when the progress is animating. I am asking if the click event goes through the viewModel or not
z

ziv kesten

03/03/2022, 3:12 PM
The progress bar is animating due to a state change from the viewModel, the blinking square was my indication that it is recomposing, even thought it has no reason too. While it is recomposing, I cannot click it, the viewModel method is not even called, that was my initial problem.
m

myanmarking

03/03/2022, 3:19 PM
quick test:
Surface(
    modifier = Modifier
        .fillMaxSize(),
    color = MaterialTheme.colors.background
) {
    var value by remember {
        mutableStateOf(0f)
    }
    LaunchedEffect(key1 = Unit) {
        while (true) {
            delay(100)
            value += 1f
        }
    }

    Row {
        Button(onClick = {
            Log.i("TAG", "Clicked")
        }) {
            Text(text = "Button: $value")
        }
        Slider(value = value, onValueChange = {}, valueRange = 0f..1000f)
    }
}
Quick test with a similar sample, it works as expected even when it is recomposing the button. hm .. interesting
maybe some animateVisibility bug, or card click bug idk =( having access to the full code would help. ViewModel code as well
but if you say the viewModel event is not reached, the problem must not be in the viewModel
wait. Maybe not it, but can you try to use the card click param, instead of the modifier created one =?
z

ziv kesten

03/03/2022, 3:27 PM
I appreciate the help, I left the computer by now, and am leaving for the weekend, but I will surly do that test you suggested on Sunday, and will update here! Thank you very much!
m

myanmarking

03/03/2022, 3:28 PM
im just guessing
i once had problems with card modifier click, i didnt realise it had an overload for that. but i dont think thats it, just trying it out
z

ziv kesten

03/03/2022, 3:29 PM
Interesting, I will look into that as well.
View count: 3