https://kotlinlang.org logo
Title
a

abbic

02/17/2023, 11:27 AM
Hi all, was just working on a util for myself and couldnt figure out if i was doing it right. i wrote this out fully naively,
@ExperimentalPermissionsApi
@Composable
fun rememberPermissionStateWithCount(
    permission: String,
    onPermissionResult: (Boolean) -> Unit = {}
): SPPermissionState {
    var count by remember {
        mutableStateOf(0)
    }

    val permissionState = rememberPermissionState(
        permission = permission,
        onPermissionResult = {
            count += 1
            onPermissionResult(it)
        }
    )
    
    return remember {
        SPPermissionState(
            permissionState = permissionState,
            dontLaunchPermissionRequest = count >= 2
        )
    }
}
So there are bound to be errors i think, but debugging through trial and error would mean a lot of work. I am effectively trying to wrap accompanist's
PermissionState
inside one of my own creation with a little added state. Is what i'm trying to achieve clear enough? does this approach work or is there an api i'm missing? for example, i may not need the remember in front of the return
s

Stylianos Gakis

02/17/2023, 11:37 AM
Since the last remember is not keyed to anything, won’t it asign to permissionState the first value that it finds
permissionState
to be and never update it? Same for evaluating if
count >= 2
only the first time?
I guess it also depends on the internals of
SPPermissionState
and if those are simple variables or
MutableState
objects. Cause it may behave differently then
a

abbic

02/17/2023, 11:38 AM
oh that makes sense, i was wondering if it would automatically "key" off the other remembered vals
SPPermissionState Isa simple data class with only vals in it
would the only necessary change be keying the final remember off count and permissionstate?
s

Stylianos Gakis

02/17/2023, 11:43 AM
No there’s no way to automatically “key” of of something, except for when using
derivedStateOf
and specifically reading data from data stored inside
MutableState
, as for example this shows (from this article).
@Composable
fun ScrollToTopButton(lazyListState: LazyListState, threshold: Int) {
  val isEnabled by remember(threshold) {
    derivedStateOf { lazyListState.firstVisibleItemIndex > threshold }
  }
  
  Button(onClick = { }, enabled = isEnabled) {
    Text("Scroll to top")
  }
}
Since
firstVisibleItemToIndex
is reading from a
MutableState
, from here and internally, at the index which is backed by MutableState
Yeah whenever you’re reading anything inside a
remember
block, you need to make sure you’re either keying it, (or using derivedStateOf + what you are reading is compose state object) otherwise you are getting whatever is read on the first pass, and it won’t keep up with further updates after that. So yeah in this case do try to key that last remember on
permissionState
and
count
.
a

abbic

02/17/2023, 11:45 AM
yes, I started trying to do this with derived state of (since I had 2 mutable states to work with) but I didn't want to return a State<> object
I don't use remember much because I usually hoist all state into the Viewmodel, thank you for the help!
s

Stylianos Gakis

02/17/2023, 11:49 AM
Yeah I understand, give this a try and see how it goes though, hope it all works for you 😄