GitXplorerGitXplorer
t

listingApp

public
43 stars
4 forks
0 issues

Commits

List of commits on branch master.
Verified
c2ce1367d5228241f77c7b05409ca3da9e3272b1

Merge pull request #37 from tunjid/tj/back-previews

ttunjid committed 2 months ago
Unverified
3e0480fa5e575e5200ee51343a6ef1d982bf8254

Clean up code

ttunjid committed 2 months ago
Unverified
8463f196956c2f45b1dcbd039feefe84b328da35

Clean code up

ttunjid committed 2 months ago
Unverified
872b3189367bcc09481f0588f1a86150753515a0

Move SplitLayoutState into AppState

ttunjid committed 2 months ago
Unverified
c64851e4910834f3b3ce56a8fd64ac9beba40112

Move splitLayoutState into AppState

ttunjid committed 2 months ago
Unverified
e68f75636f04cbe16e1c202a650ef2668612515a

Move to Compose back state for back previews

ttunjid committed 2 months ago

README

The README file for this repository.

Declarative APIS for declarative UIs

This project outlines how the declarative principles of Compose, especially how its state ownership, production and management semantics provide systemic benefits when extended to the entirety of the UI layer. I also refer to this concept as "x as state".

In particular the following are explored:

The above are used to implement a system design that supports

  • Shared element transitions using a single root LookaheadScope in the NavHost ( see AdaptiveContentHost and SharedElements.kt)
  • Predictive back animations and seeking using an immutable hoisted navigation state that is adapted on a screen configuration basis.
  • Seeding pagination pipelines from navigation arguments.
  • Persistence of navigation state to disk to restore navigation past process death, including after system reboots.

The above provide a system where "first frame readiness" is guaranteed when navigating between navigation destinations, obviating the need for legacy APIs from View such as Activity.postponeEnterTransition() and Activity.startPostponedEnterTransition().

App recordings

Portrait orientation Landscape orientation
photo portrait landscape
video portrait landscape

Screens

There are 4 screens in the app:

  • ListingFeedScreen: Vertical grid. Feed and list in a list-detail canonical layout implementation. Each feed item has a horizontal list of non paginated images.
  • ListingDetailScreen: Detail screen in a canonical list-detail implementation. Has a paginated horizontal list for media displayed.
  • GridGalleryScreen: Grid gallery layout for media, it is paginated.
  • PagerGalleryScreen: Full screen paged gallery layout for media, it is paginated. Also implements drag to dismiss with Modifier.Node.

All screens have the same state declaration:

@Composable
fun FeatureScreen(
    modifier: Modifier = Modifier,
    state: State,
    actions: (Action) -> Unit,
)

Where State is an immutable data class, however a class backed by compose state is as effective. actions is an event sink commonly used by MVI frameworks and is a stable Compose parameter.

Routing to the screen is defined higher up using remember retained semantics scoped to navigation:

    @Composable
     fun FeatureRoute() {
        val stateHolder = rememberRetainedStateHolder<ListingDetailStateHolder>(
            route = this@FeatureRoute
        )
        FeatureScreen(
            modifier = Modifier.backPreviewBackgroundModifier(),
            state = stateHolder.state.collectAsStateWithLifecycle().value,
            actions = stateHolder.accept
        )
    }

Here, based on navigation and UI state including predictive back progress, the FeatureScreen can be Composed.