dazza5000
02/28/2024, 10:06 PMTravis Griggs
02/29/2024, 12:55 AM@Composable
fun foo(bar:Bar ... ) {
// this shows up every time the composition reruns with the parent changing the bar fed to it
"enteringComposition".logged()
// this will show up on initial, but on subsequent recalls, will not fire
var zork by remember(bar) { mutableStateOf(13).logged("simple") }
// this fires every time that bar is different too
var yak by remember(bar.uuid) { mutableStateOf(42).logged("derived") }
}
Slackbot
02/29/2024, 12:41 PMYusuf Ibragimov
03/04/2024, 6:22 AMAtul Gupta
03/04/2024, 6:45 AMKapil Yadav
03/05/2024, 6:36 AMvanshg
03/05/2024, 11:02 PM/**
* Returns a [PathEffect] that draws a dashed line around the corners of a rounded rectangle
*
* @param cornerRadius The radius of the rounded corners
* @param roundedRectSize The size of the rounded rectangle
* @param extendCornerBy The amount to extend the corner dashes by. This will be distributed evenly
* on both ends of each corner
*/
fun roundedRectCornerDashPathEffect(
cornerRadius: Float,
roundedRectSize: Size,
extendCornerBy: Float = 0f,
): PathEffect {
// Each corner's length is a quarter circle
val cornerLength = (2 * Math.PI * cornerRadius / 4f).toFloat() + extendCornerBy
// There are 2 corners, so we subtract 2 * radius from the width (same goes for height)
val cornerHeight = cornerRadius + (extendCornerBy / 2)
val roundedRectWidthExcludingCorners = roundedRectSize.width - (2 * cornerHeight)
val roundedRectHeightExcludingCorners = roundedRectSize.height - (2 * cornerHeight)
return dashPathEffect(
intervals = floatArrayOf(
cornerLength,
roundedRectWidthExcludingCorners,
cornerLength,
roundedRectHeightExcludingCorners,
cornerLength,
roundedRectWidthExcludingCorners,
cornerLength,
roundedRectHeightExcludingCorners,
),
phase = cornerLength - (extendCornerBy / 2),
)
}
I use this within a Canvas like so:
// Draw the rounded rectangle cutout
drawRoundRect(
cornerRadius = CornerRadius(radius),
size = roundedRectSize,
topLeft = roundedRectTopLeft,
color = Color.Black.copy(alpha = cutoutOpacity),
style = Fill,
blendMode = BlendMode.SrcIn,
)
// Draw the corner borders
drawRoundRect(
cornerRadius = CornerRadius(radius),
size = roundedRectSize,
topLeft = roundedRectTopLeft,
color = cornerBorderColor,
style = Stroke(
width = 4.dp.toPx(),
cap = StrokeCap.Round,
pathEffect = roundedRectCornerDashPathEffect(
cornerRadius = radius,
roundedRectSize = roundedRectSize,
extendCornerBy = 16.dp.toPx(),
),
),
)
The same code results in the first image on the emulator and Compose preview, but works on a real device. If I modify the order of intervals
in the dashPathEffect, then it looks okay in Compose Preview and on an emulator, but fails similarly on a real device. Where does this indeterminism come from? I assume it is related to something about Path/CanvasAhmed na
03/07/2024, 12:17 AMTextField
?
The only references I can find is how to disable it
I want to provide my own Suggestions (depending on context) in bellow screen shotvanshg
03/07/2024, 3:52 AMkey() { rememberAnimatedVectorPainter(...) }
. This actually didn't initially work, and I actually had to wrap it _twice_: both where to painter was defined and again where it was used (2 separate composables). Finally it works. (you can see my code here)
Is it a code smell to use key() like this/does it indicate an issue with how I've created my Composables? Or is it a bug that I should file an issue for?Colton Idle
03/07/2024, 6:08 AMLaunchedEffect(navigator) {
val bundle = webViewState.viewState
if (bundle == null) {
// This is the first time load, so load the home page.
navigator.loadUrl("<https://bbc.com>")
}
}
Easy! But now I need to add an auth header. Okay not bad
navigator.loadUrl("<https://bbc.com>", "AUTH" to $token)
but now my issue is that when the token is updated, it doesn't cause a reload. How would you solve this?martmists
03/08/2024, 8:45 AMjuliocbcotta
03/08/2024, 1:20 PMKotlinLeaner
03/08/2024, 11:25 PMnavigateToDeviceSelection
, leading to redirection to ScreenName.ScreenOne
and the storage of this value within destinationState
. Subsequently, when navigating via navController
, the destination state remains unchanged, resulting in redirection to another screen. Additionally, upon invoking navigateToDeviceSelection
within ScreenName.ScreenOne.ChildTwo.route
, the destination state fails to update, rendering the LaunchedEffect
ineffective, and causing the user to remain stuck in the ScreenName.ScreenOne.ChildTwo.route
screen. To address this challenge, I seek a solution that avoids accessing destinationState
within nested composable functions, as this example is basic, and I prefer not to pass this variable to nested children.Colton Idle
03/11/2024, 7:11 AM@Composable
fun StartOnResume(block: () -> Unit) {
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
block()
}
}
lifecycle.addObserver(observer)
onDispose { lifecycle.removeObserver(observer) }
}
}
bryankeltonadams
03/11/2024, 5:19 PMgts13
03/11/2024, 8:00 PMText
. The setting is stored in DataStore
.
Only in certain screens and at specific places the Text
must change based on the settings.
So imagine we wrap this Text
in a composable named DynamicText
.
The DynamicText
can be found in ScreenA, ScreenB and ScreenD.
One way I assume to achieve this is to observe the setting in the viewmodels of those screens and update DynamicText
.
However is there any other way to achieve this? I imagine something like a singleton class "Observer" that holds the value of the setting and we can somehow pass it to DynamicText
, is that possible?
Or any other way?Travis Griggs
03/12/2024, 12:26 AMprivate fun BLEBrowserPreview() {
TwigmcTheme {
val context = LocalContext.current
BLEBrowser(scanList = remember { NearbyMCList(context) },
onConnect = { conduit -> conduit.logged("BLE CONNECT!") },
permissions = rememberMultiplePermissionsState(
listOf(
android.Manifest.permission.BLUETOOTH_SCAN,
android.Manifest.permission.BLUETOOTH_CONNECT
)
),
modifier = Modifier.fillMaxSize()
)
}
}
Unfortunately, it won't render. Digging into the render issues, I get to some stack that looks like:
java.lang.IllegalStateException: Permissions should be called in the context of an Activity
at com.google.accompanist.permissions.PermissionsUtilKt.findActivity(PermissionsUtil.kt:138)
at com.google.accompanist.permissions.MutableMultiplePermissionsStateKt.rememberMutablePermissionsState(MutableMultiplePermissionsState.kt:80)
at com.google.accompanist.permissions.MutableMultiplePermissionsStateKt.rememberMutableMultiplePermissionsState(MutableMultiplePermissionsState.kt:48)
at com.google.accompanist.permissions.MultiplePermissionsStateKt.rememberMultiplePermissionsState(MultiplePermissionsState.kt:38)
at com.nelsonirrigation.twigmc.ui.browser.ComposableSingletons$BLEBrowserKt$lambda-5$1.invoke(BLEBrowser.kt:275)
at com.nelsonirrigation.twigmc.ui.browser.ComposableSingletons$BLEBrowserKt$lambda-5$1.invoke(BLEBrowser.kt:271)
I already had to wrap my reference to BLEManager in a java.lang.AssertionError. Is this just one of those areas I shouldn't be writing a preview? The code works fine/well on a real device. Even on the simulator whose BLE appears to not really do anything.agrosner
03/12/2024, 3:22 PMvide
03/12/2024, 8:27 PMrememberCoroutineScope()
?
I'm looking to do something like this:
@Composable fun Foo() { rememberCoroutineScope().launch { delay(1000) } }
@Test fun testSomething() { ...; composeRule.advanceTimeBy(1001); ...; }
Or would I need to inject a dispatcher and manually use that anywhere I would need to control time for tests?Grigory Panko
03/13/2024, 4:27 PMString, (String) -> Unit
overload of BTF2, leaving only the one with TextFieldState
. Does this mean that Compose enforces us to hoist the TextFieldState
directly inside the ViewModel state, because including the suggested workaround with StateSyncingModifier
and etc. into each project is too cumbersome? I'm used to think that including any compose-related class (MutableState
, TextFieldState
or anything else) into my ViewModel is a bad practice (and sometimes even impossible). Or is there some better option?KotlinLeaner
03/14/2024, 12:24 PMSavedStateHandle
in my ViewModel to preserve certain states across configuration changes and navigation events. Specifically, I have a scenario where I navigate from ScreenFirst
to ScreenSecond
, and on ScreenSecond
, I toggle the visibility of a button based on the value of isBackButtonVisible
.
However, despite saving this value in the SavedStateHandle
, when I press the Back button to return to ScreenFirst
and then navigate back to ScreenSecond
, the visibility of the button is always reset to its initial state (false), instead of retaining the previously set value.
Additionally, I want to clear the back stack when navigating from one screen to another to ensure a consistent navigation flow. Although I've implemented popUpTo
to clear the back stack, it doesn't seem to affect the preservation of the isBackButtonVisible
value.
How can I ensure that the SavedStateHandle
in my ViewModel preserves the state across navigation events and back stack clearing? What could be causing the issue with the state not being retained properly?Sergio Moral
03/14/2024, 12:35 PMModifier
extension to add blur effect that is compatible with all Android versions?
Modifier.blur()
is compatible with Android 12 and above and I was trying to encapsulate all the compatible logic in one extension function.
I have tried to use graphics layer and adding a BlurEffect
to renderEffect
but with no luck in my Android 10.
Any ideas?
This is the code I have tried at this moment.
@Composable
fun Modifier.compatBlur ( radius: Float
: Modifier =
if(Build.VERSION.SDK_INT <= Build. VERSION_CODES.S)
graphicslayer {
if (radius > 0f)
renderEffect = BlurEffect(radius,radius)
}
else this.blur(radius.dp)
Timo Drick
03/14/2024, 4:51 PMMark
03/16/2024, 9:13 AMGautam Lad
03/17/2024, 3:13 PMNavHost
to get access to the navArguments
that were provided to activity that is showing the composable...see 🧵 with code snippet of what I am trying to do.Kartik
03/17/2024, 4:24 PMSwipeToDismissBox
but they are not getting triggered. I am trying to figure out why is that. I would appreciate any help in this regard
My set is up as follows
Github branch: https://github.com/manoflogan/ComposeAuthentication/blob/email/email/
1. Composable - https://github.com/manoflogan/ComposeAuthentication/blob/email/email/src/main/java/com/manoflogan/email/composables/EmailContentList.kt
2. Composable test - https://github.com/manoflogan/ComposeAuthentication/blob/email/email/src/test/java/com/manoflogan/email/composables/EmailContentListTest.kt#L88-L108.
3. Callback function that I want to invoke https://github.com/manoflogan/ComposeAuthentication/blob/email/email/src/main/java/com/manoflogan/email/composables/EmailContentList.kt#L77-L79
4. The line which fails https://github.com/manoflogan/ComposeAuthentication/blob/email/email/src/test/java/com/manoflogan/email/composables/EmailContentListTest.kt#L93-L95
I have tried to write a test as follows https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:wear/compose/compose-foundation/src/androidTest/kotlin/androidx/wear/compose/foundation/BasicSwipeToDismissBoxTest.kt
but I could not find a non wear equivalent. Any suggestions would be gratefully appreciated.Colton Idle
03/17/2024, 9:48 PMoverlayView = ComposeView(context).apply {
setContent {
Text("Overlay Text", Modifier.padding(16.dp))
}
}
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.addView(overlayView, params)
with ViewTreeLifecycleOwner not found
but if I do the same code from View land then no crash. (view system code inside 🧵 ) let me know if compose just has some weird restrictions where it can't draw like that.Prateek Kumar
03/18/2024, 10:40 AMPavel Shnyakin
03/18/2024, 1:02 PMYusuf Ibragimov
03/19/2024, 5:33 AM