rive-app / rive-app/rive-android

`TriggerProperty.valueFlow` emits an initial `TriggerUnit`, forcing every consumer to call `drop(1)`

Open
#385 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
Kotlin
Stars
538
Forks
66
PR merge metrics
No merged PRs in 30d

Description

Description

Every ViewModelProperty type in rive-android – Boolean, Number, Enum, String, and Trigger – is implemented so that its valueFlow sends one initial element as soon as the flow is collected:

Property type First element emitted
Boolean / Number / Enum / String the property’s current value
Trigger a TriggerUnit pulse

This behaviour means that UI code like collect { … } or collectAsStateWithLifecycle() executes once immediately when the screen appears, even though the user has not triggered anything. Developers therefore have to remember to append .drop(1) (or a custom filter) every time they collect one of these flows.


Reproduction
Trigger example
val vmi = rive.controller.activeArtboard!!.viewModelInstance

coroutineScope.launch {
    vmi.getTriggerProperty("sampleTrigger")
        .valueFlow          // emits TriggerUnit once on collection
        .collect { println("sampleTrigger fired!") }
}

Output on first composition:

sampleTrigger fired!   // unexpected
Boolean example
coroutineScope.launch {
    vmi.getBooleanProperty("sampleFlag")
        .valueFlow          // emits current value once on collection
        .collect { value -> println("sampleFlag = $value") }
}

Expected behaviour

Provide a way to opt out of the initial emission:

Option Summary Pros Cons
A – no initial emission Use MutableSharedFlow(replay = 0) internally and remove the eager tryEmit No boiler‑plate; intuitive Might change existing behaviour for apps that rely on it
B – alternative API Expose eventsFlow (no initial value) alongside valueFlow Keeps binary compatibility Adds another API surface
C – flag parameter valueFlow(emitInitial = false) supporting both behaviours Explicit and symmetrical Slight API bloat

Device & versions
Item Version
rive-android 10.1.6
Device samsung SM-F741Q
Android SDK 34 (Android 14)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the ViewModelProperty implementations and the valueFlow entry point, especially getTriggerProperty("sampleTrigger"). Reproduce collection of the trigger flow and compare it with the Boolean example. Done means the chosen API provides a reliable way to avoid the initial TriggerUnit while preserving the intended behavior for existing value flows.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.