Skip to content

UX & UI Concepts

Andrés Pedraza Míguez edited this page Dec 6, 2025 · 3 revisions

This project implements specific User Experience (UX) principles to ensure the app feels polished and native.

1. Progressive Disclosure & Delayed Navigation

Context: Used in selection screens (e.g., Default Currency).

When a user selects an item in a list that acts as a definitive action (single selection), we shouldn't force them to press "Back". However, navigating back immediately feels abrupt.

Implementation:

  1. User taps item.
  2. Immediate Feedback: The UI updates (checkbox appears) instantly.
  3. Delay: We wait for a short duration (e.g., 200ms) using delay().
  4. Action: Navigation pops back.

This ensures the user sees their selection was registered before the screen vanishes.

2. Preventing FOUC (Flash of Unstyled Content)

Context: Loading preferences (e.g., loading "EUR" from DataStore).

The Problem: If we initialize a ViewModel state with a default value (e.g., "EUR") while loading the real value (e.g., "USD"), the user sees a "flicker": EUR -> USD in a split second.

The Solution:

  • ViewModel: Initialize state as null.
  • UI: Use a Placeholder or Skeleton layout while the state is null.
  • Transition: Use Crossfade to smoothly reveal the content once loaded.
// ViewModel
val state = flow.stateIn(..., initialValue = null)

// UI
if (state == null) {
    Box(modifier = Modifier.size(...)) // Invisible placeholder to reserve space
} else {
    Text(state.value) // Crossfade in
}

This prevents layout shifts and jarring visual artifacts.

Clone this wiki locally