Thread
#compose-wear
    t

    Tolriq

    1 week ago
    Is there any plans to have the PositionIndicator highlight configurable? I'm facing a small issue due to rounding leading to double state update leading to blinking of the indicator. (Like a volume bar that send the volume to a remote device then receive the updated volume that is a little different and update the state).
    John Nichol

    John Nichol

    1 week ago
    I am not sure what you mean by making the highlight configurable. Perhaps you can provide some specifics of the issue you are facing. @Sergio Sancho
    Sergio Sancho

    Sergio Sancho

    1 week ago
    You can configure some of the PositionIndicator's behavior by creating your own PositionIndicatorState (you can use the existing ones as inspiration). Alternatively, for your concrete case, you can use two state variables, one to display in the position indicator, and another for the value synced from the actual device (and you can configure some of the behavior by changing how you update between them)
    t

    Tolriq

    1 week ago
    Unfortunately PositionIndicatorState does not give much access to the highlight behavior, and in my case the external volume could be changed externally so the indicator will need to be updated when the actual device change. Even with hard rounding and limitation of the possible values, the risk of value change will still be present.
    Sergio Sancho

    Sergio Sancho

    1 week ago
    Wait, I missunderstood, by highlight you mean the animation on alpha PositionIndicator does when the state changes. Right, currently we have no configuration of that. You can still use the two state variables approach, and carry changes from the actual device state to the position indicator state only when the change is significant (to avoid the highlight on rounding errors, but still animate when there is an external volumen change).
    t

    Tolriq

    1 week ago
    Yes talking about that one. Dual state looks too error prone, I'll probably go with a local copy of the indicator if there's not too much internal stuff to carry with it.
    While you are here, some insight about the other Time text stuff?
    Sergio Sancho

    Sergio Sancho

    1 week ago
    One very simple way (but it may fail on edge cases) to implement the 2-state idea is something like
    val positionIndicatorState by remember { derivedStateOf { round(actualDeviceState * K) / K } }
    One a bit more involved is to implement a PositionIndicatorState wrapper, that keeps track of the last value for positionFraction, and returns an update only if the change is big enough.
    t

    Tolriq

    1 week ago
    Yes rounding is not 100% so not worth it. The second solution will be needed if I can't easily duplicate the source due to too much internal stuff referenced.
    Sergio Sancho

    Sergio Sancho

    1 week ago
    Something like:
    fun wrap(wrapped: PositionIndicatorState) = object : PositionIndicatorState {
        var previousPositionFraction: Float = -1f
        override val positionFraction: Float
            get() = run {
                val newFraction = wrapped.positionFraction
                if (abs(previousPositionFraction - newFraction) > 0.1f) {
                    previousPositionFraction = newFraction
                }
                previousPositionFraction
            }
        ...
    }
    t

    Tolriq

    1 week ago
    Of course thanks for this nice approach don't know why I wanted to make it more complicated than needed.
    Sergio Sancho

    Sergio Sancho

    1 week ago
    No problem. One more idea:
    val deNoisedPosition = remember {
        var prev = position.value
        derivedStateOf {
            val newVal = position.value
            if (abs(newVal - prev) > 0.01f) {
                prev = newVal
            }
            prev
        }
    }
    t

    Tolriq

    1 week ago
    Ok so the last one works nice and is easy, there's just one last little point the FractionPositionIndicatorState is internal and have a forced start value of 1f, so when the indicator is first drawn if the starting position is not 0 it will animate. This is not always wanted like displaying the indicator after a gesture with a non 0 starting point. the alpha animation coupled with already an animation to display the screen containing the indicator does not look nice specially with different durations. I can easily write my own state now that we discussed that, but maybe that one should have a native solution as it does not seem as uncommon as rounding issues ?
    Actually no the first animation runs always
    Any idea about the first highlight animation ?
    Sergio Sancho

    Sergio Sancho

    6 days ago
    So, as far as I can see, the highlight animation should only trigger when the value returned by the value function changes (the positionFraction = 1f is constant, that kind of position indicator is always at the bottom/end, only the size changes). There is an animation to show the indicator since it starts as not showing and fraction position indicators are always shown. I don't think there is an easy way to avoid that.
    t

    Tolriq

    6 days ago
    The issue is that the launch is also tied to the height resolution, so even with a custom state that have the proper starting value there's still the long animation (650ms) running, way longer than a typical animation to show the containing screen 😞 Do you think this is something than can be addressed at the library level? Position indicator use many wear internal functions so is not easy to just copy paste to change.
    Sergio Sancho

    Sergio Sancho

    6 days ago
    Right, I'll see if we can add some configuration options for the animations, without making the API more complex than needed.
    t

    Tolriq

    6 days ago
    Thanks.