GithubHelp home page GithubHelp logo

compose-router's Introduction

compose-router

Version License

logo

What's this?

Routing functionality for Jetpack Compose with back stack:

  • Helps to map your whole app structure using Compose — not just the UI parts
  • Supports a single-Activity approach — no Fragments, no Navigation component needed
  • Simply branch on current routing and compose any other @Composable
  • Back stack saves the history of routing
  • Can be integrated with automatic back press handling to go back in screen history
  • Can be integrated with automatic scoped savedInstanceState persistence
  • Supports routing based on deep links (POC impl)

Compatible with Compose version 0.1.0-dev04

Sample apps

  1. Sample module #1 - app-lifelike — Displays a registration flow + logged in content with back stack

  2. Sample module #2 - app-nested-containers — Displays nested screen history on generated levels.

  3. Jetnews - fork — Built with compose-router, adding proper screen history functionality.

  4. Pokedex - compose-pokedex — Using compose-router for app structure.

Download

Available through jitpack.

Add the maven repo to your root build.gradle

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Add the dependency:

implementation 'com.github.zsoltk:compose-router:{latest-version}'

How to use

On any level where routing functionality is needed, create a sealed class to represent your routing:

sealed class Routing {
    object AlbumList : Routing()
    data class PhotosOfAlbum(val album: Album) : Routing()
    data class FullScreenPhoto(val photo: Photo) : Routing()
}

Use the Router Composable and enjoy back stack functionality:

@Composable
fun GalleryView(defaultRouting: Routing) {
    Router("GalleryView", defaultRouting) { backStack ->
        // compose further based on current routing:
        when (val routing = backStack.last()) {
            is Routing.AlbumList -> AlbumList.Content(
                onAlbumSelected = {
                    // add a new routing to the back stack:
                    backStack.push(Routing.PhotosOfAlbum(it))
                })

            is Routing.PhotosOfAlbum -> PhotosOfAlbum.Content(
                album = routing.album,
                onPhotoSelected = {
                    // add a new routing to the back stack:
                    backStack.push(Routing.FullScreenPhoto(it))
                })

            is Routing.FullScreenPhoto -> FullScreenPhoto.Content(
                photo = routing.photo
            )
        }
    }
}

For more usage examples see the example apps.

To go back in the back stack, you can either call the .pop() method programmatically, or just press the back button on the device (see next section for back press integration).

Back stack operations:

  • push()
  • pushAndDropNested()
  • pop()
  • replace()
  • newRoot()

Connect it to back press event

To ensure that back press automatically pops the back stack and restores history, add this to your Activity:

class MainActivity : AppCompatActivity() {
    private val backPressHandler = BackPressHandler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            backPressHandler.Provider {
                // Your root composable goes here
            }
        }
    }

    override fun onBackPressed() {
        if (!backPressHandler.handle()) {
            super.onBackPressed()
        }
    }
}

Connect it to savedInstanceState

Router can automatically add scoped Bundle support for your client code.

Minimal setup:

class MainActivity : AppCompatActivity() {
    private val timeCapsule = TimeCapsule()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                timeCapsule.Provider(savedInstanceState) {
                    // Your root composable goes here
                }
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        timeCapsule.onSaveInstanceState(outState)
    }
}

In client code you can now use:

@Composable
fun Content() {
    val bundle = ambient(savedInstanceState)
    var counter by state { bundle.getInt(KEY_COUNTER, 0) }

    Button(text = "Counter: $counter", onClick = {
        bundle.putInt(KEY_COUNTER, ++counter)
    })
}

Routing from deep links

Note: this is even more of a proof-of-concept only implementation than the other parts.

Example 1

Build and install app-lifelike on your device.

Open a console and type:

adb shell 'am start -a "android.intent.action.VIEW" -d "app-lifelike://go-to-profile?name=fake&phone=123123"'

This will open app-lifelike with skipped registration flow and go directly to Profile screen with fake user:

Example 2

Build and install app-nested-containers on your device.

Open a console and type:

adb shell 'am start -a "android.intent.action.VIEW" -d "app-nested://default/BGR"'

This will open app-nested-containers with (B)lue / (G)reen / (R)ed subtrees pre-selected as routing:

See MainActivity.kt, AndroidManifest.xml, and DeepLink.kt in both sample apps to see usage example.

compose-router's People

Contributors

mvarnagiris avatar shikasd avatar zsoltk avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.