Skip to content

Fix StickyHeaderContainer NONE/FADE transitions and reduce swap jitter (#4849)#4869

Merged
shai-almog merged 3 commits intomasterfrom
fix/4849-sticky-header-followups
May 5, 2026
Merged

Fix StickyHeaderContainer NONE/FADE transitions and reduce swap jitter (#4849)#4869
shai-almog merged 3 commits intomasterfrom
fix/4849-sticky-header-followups

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

Addresses the four follow-up problems reported in the last comment of #4849:

  • TRANSITION_NONE: stop hiding the sticky host during overlap — it exposed the previous section's bottom content where the slot used to be. The pinned header now stays put until an instant swap.
  • TRANSITION_FADE: combine the fade with a slide so the rising header visibly fills the slot from below while the pinned header dissolves. With fade-only the slot looked empty for most of the transition because the rising header is still well below the slot top.
  • Boundary jitter: add a 4-pixel reverse-activation hysteresis. iOS inertia bounces a few pixels past the swap boundary; without hysteresis each bounce flipped the active section, making the pinned header teleport between scroller-tracked and slot-fixed positions.
  • Transparent header bleed: the sticky host now paints the StickyHeaderContainer's own background under the pinned header. Setting bg on the container itself is now enough to stop scroller content from showing through transparent header UIIDs.

Test plan

  • mvn test -pl maven/core-unittests -Dtest=StickyHeaderContainerTest — 18/18 pass.
    • Updated noneStyleHidesStickyHostDuringOverlapnoneStyleKeepsStickyHostInPlaceDuringOverlap.
    • Updated fadeStyleReducesStickyHostOpacityWithPushfadeStyleSlidesAndFadesStickyHostWithPush (covers slide+fade).
    • New shortReverseScrollDoesNotFlipActiveSection covers the inertia hysteresis.
  • Slow-scroll the sample form on iOS and confirm the pinned header doesn't jitter at the boundary.
  • Confirm TRANSITION_NONE no longer flashes the previous section's last row when the next header crosses the slot.
  • Confirm TRANSITION_FADE shows the rising header visibly approaching the slot rather than popping in at the end.
  • Regenerate StickyHeaderFadeTransitionScreenshotTest / StickyHeaderScreenshotTest golden images on the next CI run since FADE/NONE visuals change by design.

🤖 Generated with Claude Code

#4849)

Addresses the four follow-up problems reported on #4849:

- TRANSITION_NONE: stop hiding the sticky host during overlap. Hiding it
  exposed the bottom of the previous section's content where the slot
  used to be. The pinned header now stays put until an instant swap.
- TRANSITION_FADE: combine the fade with a slide so the rising header
  visibly fills the slot from below as the pinned header dissolves.
  With fade alone the slot looked empty for most of the transition
  because the rising header is well below the slot top until the swap.
- Boundary jitter: add a 4-pixel reverse-activation hysteresis. iOS
  inertia bounces a few pixels past the swap boundary; without
  hysteresis each bounce flipped the active section, making the pinned
  header teleport between scroller-tracked and slot-fixed positions.
- Transparent header bleed: the sticky host now paints the
  StickyHeaderContainer's own background under the pinned header, so
  setting bg on the container itself is enough to keep scroller content
  from showing through transparent header UIIDs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 5, 2026

Compared 89 screenshots: 89 matched.

Native Android coverage

  • 📊 Line coverage: 9.94% (5406/54409 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.81% (26562/339885), branch 3.59% (1170/32604), complexity 4.60% (1437/31231), method 8.09% (1180/14594), class 13.42% (263/1960)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.94% (5406/54409 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.81% (26562/339885), branch 3.59% (1170/32604), complexity 4.60% (1437/31231), method 8.09% (1180/14594), class 13.42% (263/1960)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 859.000 ms
Base64 CN1 encode 227.000 ms
Base64 encode ratio (CN1/native) 0.264x (73.6% faster)
Base64 native decode 914.000 ms
Base64 CN1 decode 222.000 ms
Base64 decode ratio (CN1/native) 0.243x (75.7% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 5, 2026

Compared 89 screenshots: 89 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 417 seconds

Build and Run Timing

Metric Duration
Simulator Boot 82000 ms
Simulator Boot (Run) 5000 ms
App Install 16000 ms
App Launch 6000 ms
Test Execution 306000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 2092.000 ms
Base64 CN1 encode 2714.000 ms
Base64 encode ratio (CN1/native) 1.297x (29.7% slower)
Base64 native decode 1599.000 ms
Base64 CN1 decode 1732.000 ms
Base64 decode ratio (CN1/native) 1.083x (8.3% slower)
Base64 SIMD encode 699.000 ms
Base64 encode ratio (SIMD/native) 0.334x (66.6% faster)
Base64 encode ratio (SIMD/CN1) 0.258x (74.2% faster)
Base64 SIMD decode 613.000 ms
Base64 decode ratio (SIMD/native) 0.383x (61.7% faster)
Base64 decode ratio (SIMD/CN1) 0.354x (64.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 77.000 ms
Image createMask (SIMD on) 22.000 ms
Image createMask ratio (SIMD on/off) 0.286x (71.4% faster)
Image applyMask (SIMD off) 211.000 ms
Image applyMask (SIMD on) 148.000 ms
Image applyMask ratio (SIMD on/off) 0.701x (29.9% faster)
Image modifyAlpha (SIMD off) 291.000 ms
Image modifyAlpha (SIMD on) 202.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.694x (30.6% faster)
Image modifyAlpha removeColor (SIMD off) 324.000 ms
Image modifyAlpha removeColor (SIMD on) 149.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.460x (54.0% faster)
Image PNG encode (SIMD off) 1678.000 ms
Image PNG encode (SIMD on) 1719.000 ms
Image PNG encode ratio (SIMD on/off) 1.024x (2.4% slower)
Image JPEG encode 803.000 ms

shai-almog and others added 2 commits May 5, 2026 07:49
…d compiles

The Android port build runs javac with the JVM platform default
encoding (ASCII on the CI runner), so any non-ASCII byte in a .java
file under CodenameOne/src fails the build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
iOS and Android emulator captures of StickyHeaderFadeTransitionScreenshotTest,
reassembled from the JDK 8 instrumentation log and the iOS UI tests
artifact on the latest run for this PR. Only the FADE golden moved;
SLIDE / NONE goldens are byte-identical so they aren't touched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit dba33b4 into master May 5, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant