tylerwilson
10/22/2021, 1:50 PMRak
10/22/2021, 2:31 PMAhmet Hasim Delibas
10/22/2021, 2:36 PMChris Fillmore
10/22/2021, 3:27 PMLazyColumn
?Nick
10/22/2021, 4:16 PMval buttonStateValue = myViewModel.buttonState.collectAsState().value
MyScreen(buttonStateValue)
....MyScreen consumes the buttonStateValue, and passes it down to a bunch of other composables
Afzal Najam
10/22/2021, 5:50 PMComposables
are PascalCase except some, like updateTransition
, which is camelCase.mattinger
10/22/2021, 7:37 PMMehdi Haghgoo
10/22/2021, 8:18 PMClament John
10/23/2021, 5:22 AMAndroid75
10/23/2021, 9:15 AMInk
10/23/2021, 7:07 PMInk
10/23/2021, 10:33 PMColton Idle
10/24/2021, 5:07 AMif (viewModel.state.snackBarMessage.isNotEmpty()) {
coroutineScope.launch {
scaffoldState.snackbarHostState.showSnackbar(viewModel.state.snackBarMessage)
viewModel.state.snackBarMessage = ""
}
}
I get hit with a lint warning though.
Calls to async or launch should happen inside a LaunchedEffect and not composition
Can anyone point me in the right direction over the fix? Changing the if
with LaunchedEffect
makes the lint error go away, but I'm not sure if that's "right"/idiomatic compose here.Android75
10/24/2021, 3:02 PMAndroid75
10/24/2021, 3:02 PMitnoles
10/25/2021, 4:45 AMkierans777
10/25/2021, 6:20 AMdarkmoon_uk
10/25/2021, 7:41 AM1.1.0
will hit beta
?
It's been on alpha06
for some time (see Google Maven repo).
It has critical fixes we need to adopt regarding back button behaviour, and beta
status is significant for us.Michal Klimczak
10/25/2021, 8:51 AM/**
* Observes the callback result from previous NavController backStackEntry and makes sure,
* that it's cleared so the LiveData doesn't trigger again (by default it triggers with the old value
* for every resubscription)
*
* Ref: <https://developer.android.com/guide/navigation/navigation-programmatic#returning_a_result>
*/
fun <T> NavController.navigationCallbackFlow(argKey: String) = this
.currentBackStackEntry!!
.savedStateHandle
.getLiveData<T>(argKey)
.asFlow()
.map { this.currentBackStackEntry!!.savedStateHandle.get<T>(argKey) }
.onEach { this.currentBackStackEntry!!.savedStateHandle.remove<T>(argKey) }
.filterNotNull()
Ink
10/25/2021, 9:20 AMSergey Y.
10/25/2021, 9:41 AMline 157
, I saw the comment "Don't do this."
But why? I know that .onSizeChanged
will only fire after the first composition, and we have to wait to get the required attribute.
This seems acceptable to me.
What other ways can we get the attributes of the child layout besides writing a custom layout using Layout
composable or Modifier.layout
?
https://android-review.googlesource.com/c/platform/frameworks/support/+/1856275/7/compose/in[…]va/androidx/compose/integration/docs/phases/Phases.ktbodo
10/25/2021, 10:03 AMText("This is a test", modifier = Modifier.dynamicTextSize(14.sp))
• composable width <=100dp it should use the specified 14.sp
• composable width > 100dp it should use the specified 14.sp multiplied with a scale factor -> e.g. scalefactor = 1.5 * 14.sp = 21.sp
Can you please show me how to achieve this best? Thxjannis
10/25/2021, 10:23 AMTextField
with a TextFieldValue
. When I select a Text the onValueChange
callback is invoked correctly. However when I perform a configuration change the `onValueChange`callback is invoked again (before the recomposition is invoked). This time with wrong values. The selection is cleared.
When I use a remembersaveable
it works more or less. It seems the selection is restored with the correct values (even though the context menu on the text is missing). It seems it simply doesn't update it before the recomposition.
Since my state is more complex I store the value in my ViewModel
. Of course the value get's updated with the wrong state before the recomposition.
Any ideas how to solve this? Or is it a bug?Arpit Shukla
10/25/2021, 10:46 AManimateFloatAsState
, I see that it accepts a finishedListener
but how to provide something like an updateListener
?Ink
10/25/2021, 12:57 PMHorizontalPager
and I want to make second item visible. I"ve added itemSpacing but it doesn't work, any idea?
HorizontalPager(state = pagerState, itemSpacing = 35.dp) {
HorizontalViewPagerItem()
}
mattinger
10/25/2021, 2:42 PMalorma
10/25/2021, 3:00 PMonStart
events in compose?
Code in 🧵Bradleycorn
10/25/2021, 3:46 PMRow
that renders itself like the image here. In the Row, the red/blue box should fill the height of the row, but also not affect the measured height. Meaning, the other content should determine the height of the row, and then the red/blue box should fill that height. I was using InstrinsicSize.Min
to accomplish this. But alas, the row content has gotten complex enough that I need to use a SubComposeLayout
in it (a BoxWithConstraints
), and well, Intrinsics and SubComposeLayout don’t play nice together. I had been working on this before, and @Zach Klippenstein (he/him) [MOD] had helped me in another thread (https://kotlinlang.slack.com/archives/CJLTWPH7S/p1621712795136000), suggesting that I use a Custom Layout for the Row composable. I’m finally getting a chance to work on that. The code I’ve come up with as a starting point for my custom Layout is included in this thread. I was hoping to get some feedback to see if I’m on the right track with it, since it’s my first attempt at a custom layout….Chris Johnson
10/25/2021, 3:54 PMModifier.offset
causes recomposition infinitely when I'm not touching the screen? I'm using it together with animateIntOffset
+ user scroll.
Code in 🧵Tolriq
10/25/2021, 6:46 PMTolriq
10/25/2021, 6:46 PMAndrey Kulikov
10/25/2021, 7:13 PMTolriq
10/25/2021, 7:30 PMAndrey Kulikov
10/25/2021, 7:52 PMTolriq
10/25/2021, 7:58 PMval items = remember(lazyPagingItems.itemCount) {
derivedStateOf {
List(lazyPagingItems.itemCount) { it }.windowed(stepSize, stepSize, true)
}
}
LazyColumn(
state = lazyListState,
contentPadding = PaddingValues(vertical = 8.dp),
content = {
item {
Header(viewModel)
}
items(items.value) { items ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 4.dp)
) {
items.map { lazyPagingItems[it] }.forEach {
AlbumEntryGrid(it, viewModel.getThumbnailImagePath(it)) {
if (it != null) {
navigator.navigateTo(AlbumDetailsScreenDestination(it))
}
}
}
repeat(stepSize - items.size) {
Spacer(modifier = Modifier.weight(1f))
}
}
}
}
)
@Composable
fun RowScope.AlbumEntryGrid(mediaItem: MediaItem?, thumbnailImagePath: ImagePath, onRowClick: () -> Unit) {
val finalMediaItem = mediaItem ?: MediaItem(title = "Placeholder")
Box(
Modifier
.clickable { onRowClick() }
.aspectRatio(1f)
.weight(1f)
.padding(4.dp)
.clip(RoundedCornerShape(8.dp)),
) {
val imageRequest = ImageRequest(
thumbnailImagePath,
exactSize = false,
debugTag = "AlbumEntryGrid"
)
Image(
imageRequestPainter = rememberImageRequestPainter(imageRequest = imageRequest),
contentDescription = null,
error = @Composable { Error(finalMediaItem) },
placeHolder = @Composable { SurfacePlaceHolder() },
contentScale = ContentScale.FillBounds,
modifier = Modifier
.aspectRatio(1f)
)
}
}
remember(lazyPagingItems.itemCount) {
derivedStateOf {
List(lazyPagingItems.itemCount) { it }.windowed(stepSize, stepSize, true)
}
}
Is triggering a recalculation of the derived state and so the tree when compose paging load a new page. (But the perf issue is also ocutring when all pages are loaded so it's not the root cause).
Is there something wrong with that approach to have a stable state that contains a list of number that must only be recreated when the actual itemcount change ?Andrey Kulikov
10/25/2021, 8:18 PMTolriq
10/25/2021, 8:23 PMval lazyListState = rememberLazyListState()
It's just defined earlier as I use the same when switching from list to grid@Composable
inline fun LogCompositions(tag: String) {
if (ENABLE_DEBUG_COMPOSITION_LOGS && BuildConfig.DEBUG) {
val ref = remember { Ref(0) }
SideEffect {
ref.value++
Logger.logger.logError(tag, "Compositions: ${ref.value}", null, true)
}
}
}
val items = List(14000) { listOf(it, it, it) }
LazyColumn(
state = rememberLazyListState(),
content = {
items(items) { items ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(4.dp)
.background(Color.Red)
) {
items.forEach {
Surface(
color = Color.DarkGray,
modifier = Modifier
.clickable { /*onRowClick()*/ }
.weight(1f)
.aspectRatio(5f)
.padding(4.dp)) {}
}
}
}
}
)