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-wear
  • z

    Zach Klippenstein (he/him) [MOD]

    10/01/2021, 5:32 PM
    Any of you want to plug this channel in #compose? Most people won’t notice it until then.
    a
    • 2
    • 1
  • y

    yschimke

    10/04/2021, 8:50 AM
    Any good Google or Community Wear Compose samples we can point to?
    j
    j
    +2
    • 5
    • 13
  • a

    Ash

    10/08/2021, 9:24 PM
    Super excited. Have been asking for this for years.
    ⏱️ 1
    y
    • 2
    • 8
  • y

    yschimke

    10/13/2021, 7:03 AM
    With Wear Navigation, what's the guidance for making a single large navigation graph with deeplinks, vs linking out to different distinct Activity's? Would something like settings be best as a separate Activity? Or does it cause any noticeable UX difference (backstack, ui transitions?).
    j
    i
    +3
    • 6
    • 10
  • j

    John Nichol

    10/14/2021, 4:28 PM
    Compose for WearOS Alpha08 was release last night - https://developer.android.com/jetpack/androidx/releases/wear-compose#1.0.0-alpha08. with links to some of the great UX Guidelines linked from the KDoc as well as improvements to SwipeToDismiss and some new samples again linked from KDoc - One API change to watch out for: We moved the body() of Cards to a trailing lambda.
    8️⃣ 6
    👍 9
    c
    • 2
    • 1
  • j

    John O'Reilly

    10/15/2021, 9:16 AM
    Are there any components/styles etc to ensure that text isn't clipped like this?
    👀 2
    j
    z
    +3
    • 6
    • 17
  • n

    Noop

    10/16/2021, 6:31 AM
    How to use Rotary input for Column?
    ➕ 2
    s
    j
    +2
    • 5
    • 9
  • y

    yschimke

    10/19/2021, 8:52 AM
    @John Nichol Looking at the material spec, the support for input chips with a delete button, seems to indicate a secondary action in Chip might be ok. Obviously the primary action is opening the detail view. Are there guidelines for Chips in Wear like that? How to have a secondary action like Download instead of Open/Play?
    j
    • 2
    • 2
  • g

    Garan Jenkin

    10/21/2021, 5:46 PM
    LazyListState
    supports
    scrollToItem()
    but
    ScalingLazyListState
    does not. Is this something that might come in the future, or consciously omitted?
    🍿 1
    ➕ 1
    y
    j
    • 3
    • 2
  • a

    Alex Bravo

    10/21/2021, 10:07 PM
    I know it might be a little early to ask, but is there a plan for betas/stable of Compose Wear? I’m trying to determine when I can start using it in production code.
    ⏳ 1
    j
    • 2
    • 2
  • y

    yschimke

    10/22/2021, 8:53 AM
    Wanted to call out some regular mobile compose components that seem to just work Swipe to Refresh https://google.github.io/accompanist/swiperefresh/
    👍 2
    • 1
    • 1
  • y

    yschimke

    10/26/2021, 12:05 PM
    A pattern I'm trying for compose previews
    @Composable
    fun MyAppThemePreview(
        round: Boolean = true,
        content: @Composable () -> Unit,
    ) {
        MyAppTheme {
            if (round) {
                Box(Modifier.fillMaxSize().background(Color.White)) {
                }
                Box(modifier = Modifier.fillMaxSize().clip(CircleShape).background(Color.DarkGray)) {
                    content()
                }
            } else {
                Box(modifier = Modifier.fillMaxSize().background(Color.DarkGray)) {
                    content()
                }
            }
        }
    }
    👍 2
    j
    j
    • 3
    • 10
  • j

    John Nichol

    11/03/2021, 6:35 PM
    Wear Compose alpha10 is out - https://developer.android.com/jetpack/androidx/releases/wear-compose#1.0.0-alpha10. Only a week since the last alpha we released at Android Dev Summit, but it includes a new InlineSlider component and some improvements to SwipeDismissNavHost.
    :party-parrot: 11
    👍 2
    t
    • 2
    • 2
  • y

    yschimke

    11/04/2021, 8:55 AM
    Is there a good sample of Ambient Mode with Wear Compose? Is it extend FragmentActivity or AppCompatActivity, use the Callback to set Ambient mode in a ViewModel state field and have a simplified UI code path when enabled?
    j
    • 2
    • 2
  • g

    Gabriel Gircenko

    11/04/2021, 11:21 AM
    I'm struggling with making the Compose equivalent of the ViewPager2 with the LazyRow. Is there a solution to this? This is the whole code snippet where you can see that I have tried out a few approaches:
    @Composable
        private fun ListOfHomePages(rows: List<PageItemUIData>) {
            val listState = rememberLazyListState()
            val listScope = rememberCoroutineScope()
            val scrollState = rememberScrollState()
            var index by remember { mutableStateOf(0) }
    
            LazyRow(
                modifier = Modifier
                    .fillMaxSize()
                    .background(color = colorResource(id = R.color.black)),
                state = listState
            ) {
                items(rows) { item: PageItemUIData ->
                    if (!listState.isScrollInProgress) {
                        listScope.launch {
                            listState.animateScrollToItem(index)
                        }
                        /*if (listState.isScrollingUp()) {
                            listScope.launch {
                                listState.animateScrollToItem(listState.firstVisibleItemIndex + 1)
                            }
                        } else if (listState.isScrollingDown()) {
                            listScope.launch {
                                listState.animateScrollToItem(listState.firstVisibleItemIndex - 1)
                            }
                        }*/
                    }
    
                    PageItem(
                        painter = item.painter,
                        iconContentDescription = item.iconContentDescription,
                        title = item.title,
                        backgroundGradientStart = item.backgroundGradientStart,
                        backgroundGradientEnd = item.backgroundGradientEnd,
                        backgroundGradientOffset = item.backgroundGradientOffset,
                        modifier = Modifier.onGloballyPositioned { coordinates ->
                            index = coordinates.positionInParent().x.roundToInt()
                        }
                    )
                }
            }
        }
    I'm pretty new to Compose too and don't understand how to run a coroutine just once instead of every composition...
    y
    a
    j
    • 4
    • 7
  • y

    yschimke

    11/04/2021, 2:23 PM
    Material (pre-compose) seems to have a well supported notion of custom typography - https://material.io/blog/android-material-theme-type Does this concept exist in compose Material (wear or mobile)? OR you should just follow the same approach with your own CompositionLocalProvider? Or generally people hardcode fonts inline and just use MaterialTheme for it's effect on Material widgets like Cards or Buttons?
    a
    • 2
    • 4
  • b

    barat

    11/07/2021, 9:58 AM
    Hello. I am composing the app using only composable in my application.   Currently, there is one stumbling block, and when composing a screen without scrolling in a circular wear device, there is a phenomenon that items overflow start and end. If composable is not used, it would have been solved by using boxInset or circular activity, but how can do this with composable?  If you look at the player screen of YouTube Music, you can see that texts are properly applied to the start and end of screens. Does wear composable have this function? Currently, I set a guideline using the length of the inscribed rectangle, and apply the item not to exceed the guideline. Please let me know if there is a better way.
    BoxWithConstraints() {
        val absoluteValue = (maxWidth - (maxWidth / sqrt(2f)))/2
    
        ConstraintLayout(modifier = Modifier.fillMaxSize()) {
            val absoluteStartGuideline = createGuidelineFromAbsoluteLeft(absoluteValue)
    y
    j
    • 3
    • 3
  • a

    Austin Nelson

    11/07/2021, 1:06 PM
    Is there any better way to add Text Input to Compose for Wear? I'm currently using a BasicTextField (seems to be the only thing available). The keyboard pops up (but flickers and you have to click it twice), but I don't get any text in the keyboard preview as I'm typing. If I exit the keyboard view, the text does appear in the UI and if I tap on the BasicTextField again, then the previously entered text will appear in the keyboard layout.
    @Composable
    fun TextField() {
        var value by remember { mutableStateOf(TextFieldValue("")) }
        val keyboardController = LocalSoftwareKeyboardController.current
    
        BasicTextField(
            value = value,
            onValueChange = { value = it },
    
            keyboardOptions = KeyboardOptions(
                imeAction = ImeAction.Done,
                keyboardType = KeyboardType.Number
            ),
            keyboardActions = KeyboardActions(
                onDone = { keyboardController?.hide() }),
            decorationBox = { innerTextField ->
                Row(
                    Modifier
                        .background(Color.DarkGray, RoundedCornerShape(percent = 50))
                        .padding(12.dp)
                ) {
    
                    if (value.text.isEmpty()) {
                        Text("Manual IP Address")
                    }
                    innerTextField() 
                }
            },
        )
    }
    j
    • 2
    • 2
  • g

    Garan Jenkin

    11/08/2021, 2:43 PM
    I have an app where the navigation is on some occasions controlled by the state of a ForegroundService. At the moment, to make the screen navigate on a change to the state held in the Service, I use a
    LaunchedEffect
    that sits outside of the
    NavHost
    . You can see this here: https://github.com/garanj/wearwind/blob/main/app/src/main/java/com/garan/wearwind/FanActivity.kt#L115 So when the watch successfully connects to the fan, the screen transitions to the Connected screen, but it avoids the situation where when the user swipes back from the Connected screen they may hit the Connect screen but bounce back to the Connected screen as the fan hasn't disconnected yet... but is this a bad idea to have this navigation logic here? I've been trying to have it within each screen but with no success yet.
    j
    y
    • 3
    • 7
  • g

    Garan Jenkin

    11/08/2021, 2:47 PM
    Entirely out of my depth so any help most welcome! 🙂
    y
    s
    • 3
    • 4
  • s

    Steve Bower [G]

    11/09/2021, 9:24 AM
    Nikit Bhandari has written a post on how to implement Navigation in Compose for Wear OS using SwipeDismissableNavHost - see https://proandroiddev.com/compose-for-wear-os-navigation-40c42bce9df7
    👀 4
    :thank-you: 2
    y
    n
    • 3
    • 7
  • g

    Garan Jenkin

    11/11/2021, 11:22 AM
    I'm sure I'm missing something obvious, but when I add a preview, the preview looks like it's a phone... how do you change to a watch screen shape and size?
    ✅ 1
    s
    c
    • 3
    • 5
  • g

    Garan Jenkin

    11/14/2021, 11:39 AM
    At the moment, it's pretty hard-coded:
    Text(
        text = speed,
        color = Colors.primary,
        style = LocalTextStyle.current.copy(fontSize = 108.sp),
        fontStyle = FontStyle.Italic,
        fontWeight = FontWeight.ExtraBold
    )
    But as per @yschimke’s comment it would be great to know how to best make use of Theming to support this cleanly? (I like Yuri's suggestion of
    WearWindTheme.typography.majorItem
    ) ? Any thoughts?
    y
    c
    • 3
    • 5
  • y

    yschimke

    11/19/2021, 12:44 PM
    Are there any samples for Secondary actions on Chips? Or UI guidance?
    j
    • 2
    • 3
  • a

    Andrew Leung

    11/24/2021, 9:30 PM
    Hello, is the AlertDialog usable in Compose Wear? If not, what would be an alternative component to use for similar interactions?
    a
    j
    +2
    • 5
    • 6
  • g

    Garan Jenkin

    12/06/2021, 12:45 PM
    Just trying the stepper, and one part confused me! To try it out, tried a hard-coded example, which illustrates:
    Stepper(
        value = curr.value,
        onValueChange = { value ->
            curr.value = value
            Log.i(TAG, "New value: $value")
        },
        valueRange = 100.0f .. 220.0f,
        steps = (220 - 100) / 5 - 1
    ) {
    Aim was to be able to have a range of 100 to 220 and be able to step values by 5. The part that confused me was the
    steps
    value. Docs say "Step value is calculated as the difference between min and max values divided by steps+1". So, to get the correct step size, I have to subtract one from what I initially thought as the intuitive number of steps (
    (220 - 100) / 5
    ). It's no big deal, reading the documentation solved it, just wasn't sure why "steps+1", though I've likely just misunderstood something.
    y
    s
    • 3
    • 9
  • g

    Garan Jenkin

    12/07/2021, 10:33 AM
    This is what I added - probably an abuse of the Stepper 🙂 but having both the min and max on one screen felt right, especially as min < max condition is enforced. Two things I noted: • At 2s and 17s is that there is the occasional flicker of a value that isn't either ending 0 or 5, but is instead 4 or 9, before it gets corrected. Highly likely I'm doing something wrong, but I wonder if you've seen this too @Steve Bower [G]? nb. only saw this on the emulator, not on real devices. • Is it planned that the stepper can use the bezel for + and - input? (Or did I fail to configure that, but it's already possible?). (My Stepper use: https://github.com/garanj/wearwind/pull/6/files#diff-bd7e769b499a685bcb1751d4b829ca03039076cb994ee52d5086f17a441703c5 )
    Screen Recording 2021-12-07 at 9.40.35 AM.mov
    j
    l
    +3
    • 6
    • 15
  • y

    yschimke

    12/08/2021, 10:40 AM
    As all cute workarounds go, @saryong your Rotary Event Handler will break in Compose 1.1.0-beta04. cc @John O'Reilly
    👍 2
    j
    b
    s
    • 4
    • 13
  • y

    yschimke

    12/13/2021, 8:07 AM
    What is the typical pattern for AlertDialog when used with navigation? https://github.com/yschimke/rememberwear/blob/main/wear/src/main/kotlin/com/google/wear/soyted/ui/RememberWearAppScreens.kt#L105-L128
    composable(
                        Screens.LoginDialog.route
                    ) {
                        AlertDialog(
                            title = {
    then
    positiveButton = {
                                Button(onClick = {
                                    viewModel.continueLogin()
                                    navController.popBackStack()
    j
    i
    s
    • 4
    • 21
  • a

    Austin Nelson

    12/14/2021, 1:58 AM
    After upgrading
    androidx.hilt:hilt-navigation-compose
    to
    1.0.0-beta01
    I am now getting this error:
    You cannot access the NavBackStackEntry's ViewModels until it is added to the NavController's back stack (i.e., the Lifecycle of the NavBackStackEntry reaches the CREATED state).
    But I commented out all of my ViewModel stuff and it's still erroring out. Can anyone explain what changed? This is basically all I have:
    SwipeDismissableNavHost(
        navController = navController,
        startDestination = "start",
        modifier = Modifier.background(MaterialTheme.colors.background)
    ) {
    
        composable("start") {
    //                val mainViewModel = hiltViewModel<MainViewModel>()
    //                val uiState = mainViewModel.uiState.collectAsState()
    
            Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Text("uiState.value")
            }
        }
    }
    👍 1
    i
    • 2
    • 2
Powered by Linen
Title
a

Austin Nelson

12/14/2021, 1:58 AM
After upgrading
androidx.hilt:hilt-navigation-compose
to
1.0.0-beta01
I am now getting this error:
You cannot access the NavBackStackEntry's ViewModels until it is added to the NavController's back stack (i.e., the Lifecycle of the NavBackStackEntry reaches the CREATED state).
But I commented out all of my ViewModel stuff and it's still erroring out. Can anyone explain what changed? This is basically all I have:
SwipeDismissableNavHost(
    navController = navController,
    startDestination = "start",
    modifier = Modifier.background(MaterialTheme.colors.background)
) {

    composable("start") {
//                val mainViewModel = hiltViewModel<MainViewModel>()
//                val uiState = mainViewModel.uiState.collectAsState()

        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("uiState.value")
        }
    }
}
👍 1
i

Ian Lake

12/14/2021, 2:09 AM
That sounds like this issue, which is already fixed for the next release: https://issuetracker.google.com/issues/207328687
👍 2
👍🏽 1
👍🏻 1
a

Austin Nelson

12/14/2021, 2:11 AM
Thanks! Didn't see that
View count: 8