Model-driven navigation for Jetpack Compose

Overview

Appyx

Build Maven Central GitHub license

Project page

https://bumble-tech.github.io/appyx

License

Copyright 2021 Bumble.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Replicating startDestinationRoute.popUpto() from compose navigation

    Replicating startDestinationRoute.popUpto() from compose navigation

    Hello maintainers. Thanks a lot for this library! It really simplifies work a lot, and I am replacing navigation-compose with it. However, I want to know if there is a way to replicate what startDestinationRoute.popUpto() in navigation compose does. That is, when navigating to 3 different screens sequentially, on tapping the back button on the 3rd screen, I should come back to the first screen. Thanks again!

    opened by KotlinGeekDev 12
  • Consider introducing a Github merge queue

    Consider introducing a Github merge queue

    Currently all branches are merged into main without requiring being up to date with main.

    This could mean we merge an old branch that has a breaking change, and the main branch needs to be fixed.

    Also, potentially if we introduce stricter static code analysis, potentially this older branch will increase our tech debt

    We should consider using a merge queue to avoid this problem: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue

    Otherwise we could also enforce that all PRs need to be up to date with main, but I believe that will be far more annoying.

    build & CI 
    opened by LachlanMcKee 6
  • onBackPressed memory leak

    onBackPressed memory leak

    When I quit my app using the back button on a phone running SDK 29, Leak Canary reports a memory leak.

    If I use the fix reported here: https://issuetracker.google.com/issues/139738913, the leak is fixed.

    override fun onBackPressed() {
            // Fix for Memory Leak: https://issuetracker.google.com/issues/139738913
            if (Build.VERSION.SDK_INT == 29 && !onBackPressedDispatcher.hasEnabledCallbacks()) {
                finishAfterTransition()
            } else {
                super.onBackPressed()
            }
        }
    

    However, if I use Appyx NodeActivity with a RootNode, I get the memory leak again.

    bug 
    opened by duanemalcolm 5
  • [DRAFT] Gesture navigation API + swipe implementation

    [DRAFT] Gesture navigation API + swipe implementation

    Description

    Basic gesture API + Swipe implementation. Implemented as a Modifier which is applied to container composable.

    If we agree on the API more gestures to come:

    • draggable
    • multi touching
    • ..

    Fixes https://github.com/bumble-tech/appyx/issues/97

    https://user-images.githubusercontent.com/5773436/186649066-32f5b004-6ce2-4587-bca2-84000399fff7.mp4

    Check list

    • [ ] I have updated CHANGELOG.md if required.
    • [ ] I have updated documentation if required.
    enhancement 
    opened by KovalevAndrey 5
  • Backstack: triggering navigation mid-transition discards previous transition

    Backstack: triggering navigation mid-transition discards previous transition

    The issue seems to be happening when doing consecutive operations (push or pop), best explained with video:

    https://user-images.githubusercontent.com/20369236/177795492-c806aeaa-2046-467a-ad29-7ff85852a7c6.mp4

    Full sample code:

    class RootActivity : NodeActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        WindowCompat.setDecorFitsSystemWindows(window, false)
    
        setContent {
          MaterialTheme {
            NodeHost(
              integrationPoint = integrationPoint,
              factory = { buildContext ->
                RootNode(
                  buildContext = buildContext,
                  backstack = BackStack(
                    initialElement = RootNode.Routing.Child("Root"),
                    savedStateMap = buildContext.savedStateMap,
                  )
                )
              },
            )
          }
        }
      }
    }
    
    class RootNode(
      buildContext: BuildContext,
      private val backstack: BackStack<Routing>,
    ) : ParentNode<RootNode.Routing>(
      routingSource = backstack,
      buildContext = buildContext,
    ) {
      sealed class Routing : Parcelable {
        @Parcelize
        data class Child(val id: String) : Routing()
      }
    
      @Composable
      override fun View(modifier: Modifier) {
        Surface(
          modifier = modifier.fillMaxSize(),
          color = Color.White
        ) {
          Children(
            routingSource = backstack,
            transitionHandler = rememberBackstackSlider(
              transitionSpec = { tween(2000, easing = LinearEasing) }
            ),
          )
        }
      }
    
      override fun resolve(routing: Routing, buildContext: BuildContext): Node {
        return ChildNode(
          name = when (routing) {
            is Routing.Child -> routing.id
          },
          buildContext = buildContext,
          pushNew = { backstack.push(Routing.Child(UUID.randomUUID().toString())) },
        )
      }
    }
    
    class ChildNode(
      private val name: String,
      private val pushNew: () -> Unit,
      buildContext: BuildContext
    ) : Node(buildContext = buildContext) {
    
      private val colors = listOf(
        manatee,
        sizzling_red,
        atomic_tangerine,
        silver_sand,
        md_pink_500,
        md_indigo_500,
        md_blue_500,
        md_light_blue_500,
        md_cyan_500,
        md_teal_500,
        md_light_green_500,
        md_lime_500,
        md_amber_500,
        md_grey_500,
        md_blue_grey_500
      )
    
      private val colorIndex =
        buildContext.savedStateMap?.get(KEY_COLOR_INDEX) as? Int ?: Random.nextInt(colors.size)
      private val color = colors[colorIndex]
    
      override fun onSaveInstanceState(state: MutableSavedStateMap) {
        super.onSaveInstanceState(state)
        state[KEY_COLOR_INDEX] = colorIndex
      }
    
      @Composable
      override fun View(modifier: Modifier) {
        Box(
          modifier = Modifier
            .fillMaxSize()
            .background(
              color = color,
              shape = RoundedCornerShape(6.dp)
            )
        ) {
          Column(
            modifier = Modifier.padding(24.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp),
          ) {
            Text("Child ($name).")
            Row {
              // Local UI state should be saved too (both in backstack and onSaveInstanceState)
              var counter by rememberSaveable { mutableStateOf(0) }
              Text(text = "Counter $counter", modifier = Modifier.align(CenterVertically))
              Spacer(modifier = Modifier.width(16.dp))
              Button(onClick = { counter++ }, content = { Text("Increment") })
            }
            Row {
              Button(onClick = { navigateUp() }, content = { Text("Go up") })
            }
            Row {
              Button(onClick = pushNew, content = { Text("Push new") })
            }
          }
        }
      }
    
      companion object {
        private const val KEY_COLOR_INDEX = "ColorIndex"
      }
    }
    
    bug 
    opened by steelahhh 4
  • Node does is missing onDestroy callback in some cases

    Node does is missing onDestroy callback in some cases

    More info here

    Similarly, can be reproduced following these steps:

    1. Open sample sandbox
    2. Click explicit navigation button
    3. Click Push two
    4. In Grandchild one click Navigate to child one
    5. Observe lifecycle events in the logs. On destroy is not received
    bug 
    opened by KovalevAndrey 3
  • Update ReadME - Where is

    Update ReadME - Where is "Get started?"

    Hi, I am newbie to this and I went to your website and tried to find a page where I can get started like calling libraries inside Gradle:app and so forth but I can't find it. It would be nice if you guys could update better from the web page to here. Thanks

    documentation 
    opened by OshedheMunasinghe 3
  • Introduced dependency diff github action

    Introduced dependency diff github action

    Description

    Adds the ability to see dependency changes within PRs.

    You can see the diff in action within this PR (https://github.com/LachlanMcKee/appyx/pull/2) - It needs to be raised in my fork as this needs to be the base branch.

    Check list

    • [x] I have updated CHANGELOG.md if required.
    • [x] I have updated documentation if required.
    opened by LachlanMcKee 3
  • Fix IntegrationPoint memory leak created by ActivityIntegrationPoint

    Fix IntegrationPoint memory leak created by ActivityIntegrationPoint

    Description

    ActivityIntegrationPoint leaking Activity instances since ActivityIntegrationPoint holds a strong reference to the Activity. WeakHashMap is unable to clear the entry since the same activity instance is being used as key and also in the value object

    ┬───
    │ GC Root: Thread object
    │
    ├─ android.net.ConnectivityThread instance
    │    Leaking: NO (PathClassLoader↓ is not leaking)
    │    Thread name: 'ConnectivityThread'
    │    ↓ Thread.contextClassLoader
    ├─ dalvik.system.PathClassLoader instance
    │    Leaking: NO (ActivityIntegrationPoint↓ is not leaking and A ClassLoader is
    │    never leaking)
    │    ↓ ClassLoader.runtimeInternalObjects
    ├─ java.lang.Object[] array
    │    Leaking: NO (ActivityIntegrationPoint↓ is not leaking)
    │    ↓ Object[884]
    ├─ com.bumble.appyx.core.integrationpoint.ActivityIntegrationPoint class
    │    Leaking: NO (a class is never leaking)
    │    ↓ static ActivityIntegrationPoint.integrationPoints
    │                                      ~~~~~~~~~~~~~~~~~
    ├─ java.util.WeakHashMap instance
    │    Leaking: UNKNOWN
    │    Retaining 169.6 kB in 3954 objects
    │    ↓ WeakHashMap.table
    │                  ~~~~~
    ├─ java.util.WeakHashMap$Entry[] array
    │    Leaking: UNKNOWN
    │    Retaining 169.5 kB in 3951 objects
    │    ↓ WeakHashMap$Entry[0]
    │                       ~~~
    ├─ java.util.WeakHashMap$Entry instance
    │    Leaking: UNKNOWN
    │    Retaining 83.2 kB in 1926 objects
    │    referent instance of co.zuper.android.ui.host.HostActivity with mDestroyed
    │    = true
    │    ↓ WeakHashMap$Entry.value
    │                        ~~~~~
    ├─ com.bumble.appyx.core.integrationpoint.ActivityIntegrationPoint instance
    │    Leaking: UNKNOWN
    │    Retaining 83.2 kB in 1925 objects
    │    activity instance of co.zuper.android.ui.host.HostActivity with mDestroyed
    │    = true
    │    ↓ ActivityIntegrationPoint.activity
    │                               ~~~~~~~~
    ╰→ co.zuper.android.ui.host.HostActivity instance
    ​     Leaking: YES (ObjectWatcher was watching this because co.zuper.android.ui.
    ​     host.HostActivity received Activity#onDestroy() callback and
    ​     Activity#mDestroyed is true)
    ​     Retaining 82.9 kB in 1916 objects
    ​     key = 005ec729-daaa-43df-a6d2-2f97825f9d7a
    ​     watchDurationMillis = 18279
    ​     retainedDurationMillis = 13277
    ​     mApplication instance of co.zuper.android.ZuperApp
    ​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
    
    METADATA
    
    Build.VERSION.SDK_INT: 33
    Build.MANUFACTURER: Google
    LeakCanary version: 2.9.1
    App process name: co.zuper.android.dev
    Class count: 30112
    Instance count: 243224
    Primitive array count: 143091
    Object array count: 38493
    Thread count: 31
    Heap total bytes: 31331321
    Bitmap count: 28
    Bitmap total bytes: 900521
    Large bitmap count: 0
    Large bitmap total bytes: 0
    Stats: LruCache[maxSize=3000,hits=117858,misses=248001,hitRate=32%]
    RandomAccess[bytes=12538085,reads=248001,travel=81765454152,range=37319569,size=
    46458866]
    Analysis duration: 4738 ms
    

    Check list

    • [x] I have updated CHANGELOG.md if required.
    • [x] I have updated documentation if required.
    bug 
    opened by RationalRank 3
  • Issue #34 Add unit and instrumentation tests to github action

    Issue #34 Add unit and instrumentation tests to github action

    Description

    Ensure that unit tests and instrumentation tests are run as part of the PR

    Fixes #34

    Check list

    • [x] I do not need to update CHANGELOG.md.
    • [x] I do not need to update the documentation.
    enhancement 
    opened by LachlanMcKee 3
  • Add unit test support

    Add unit test support

    Description

    This pull request adds a unit testing API. New helpers: InteractorTestHelper NodeTestHelper ParentNodeTestHelper

    To make testing easier you can use: FeatureStub NodeViewStub instead of relying on mocks.

    Check list

    • [x] I have updated CHANGELOG.md if required.
    • [x] I have updated documentation if required.
    opened by vladcipariu91 3
  • Implicit Navigation and state restoration.

    Implicit Navigation and state restoration.

    I've a question, given the exemple here: https://bumble-tech.github.io/appyx/navigation/implicit-navigation/#use-case-2

    We listen to the UserRepository in the RootNode to then branch the right LoggedInNode or NotLoggedInNode. We make the listening lifecycle aware so we stop listening to UserRepository when RootNode is destroyed.

    init {
            userRepository.isLoggedIn()
                .distinctUntilChanged()
                .onEach { isLoggedIn ->
                    if (isLoggedIn) {
                            backstack.replace(NavTarget.LoggedInNode)
                        } else {
                            backstack.replace(NavTarget.NotLoggedInNode)
                        }
                    }
                .launchIn(lifecycleScope)
        }
    

    So, if we provoke a configuration change, the activity and all the nodes will be destroyed and recreated. The right node will be restored, but we'll also start listening to the UserRepository again, so we'll replace the restored Node by a new one.

    Not sure how we can manage this case, any idea?

    opened by ganfra 4
  • ViewModel POC

    ViewModel POC

    Description

    This PR demonstrates how VM can be used and scoped to a Node using reflection API.

    By design VM is stored in a ViewModelStore class and lives as long as activity lives.

    The desired behaviour is the following:

    1. VM is created when Node is created
    2. VM is persistent when Node is moved in DESTROY state and Activity is changing configuration
    3. VM is destroyed when Node is moved in DESTROY state and Activity IS NOT changing configuration

    This behaviour can not be achieved using public API as it's not possible to clear only one VM from ViewModelStore. It has only one public method –ViewModelStore.clear()which clears allVMs.

    I the meantime I'm exploring alternative solutions.

    https://user-images.githubusercontent.com/5773436/207447633-65f79414-2313-4d7b-b453-464c4e51de30.mp4

    Check list

    • [ ] I have updated CHANGELOG.md if required.
    • [ ] I have updated documentation if required.
    opened by KovalevAndrey 3
  • NodeConnector intake is not disposed when a node is destroyed

    NodeConnector intake is not disposed when a node is destroyed

    It seems that not disposing NodeConnector.intake when a Node is destroyed is a bug.

    Please let me know if this is intended. It could also potentially be a breaking change, so perhaps we need to throw an error if it happens

    bug 
    opened by LachlanMcKee 0
  • ViewModel example

    ViewModel example

    The FAQs callout an example with ViewModels was coming soon, but I couldn't find an associated tracking issue 😄

    I imagine it might look something like HiltSupport from the Hilt support FAQ?

    opened by dandc87 0
Releases(1.0.1)
  • 1.0.1(Nov 22, 2022)

    • #268Fixed: PermanentChild now does not crash in UI tests with ComposeTestRule.
    • #276Fixed: Back press handlers order is fixed for RIBs-Appyx integration.
    • #272Changed: attachWorkflow renamed to attachChild. executeWorkflow renamed to executeAction.
    • #272Added: NodeReadyObserver plugin to observe when the Node is ready
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Oct 31, 2022)

    • #247Added: Added EmptyNavModel to core for cases in which a ParentNode only uses PermanentChild. The DummyNavModel test class is deprecated.
    • #250Updated: Jetpack Compose to 1.3.0
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0-rc02(Oct 21, 2022)

  • 1.0.0-rc01(Oct 13, 2022)

    • #214Breaking change: AppyxViewTestRule stops supporting automatic launching activity. Activities should be started explicitly in tests.
    • #197Breaking change: ParentNodeView does not implement plugin anymore. Node instance is retrieved via LocalComposition. AppyxParentViewTestRule and AbstractParentNodeView have been removed.
    • #196Breaking change: InteropBuilder now should be supplied with Appyx IntegrationPointProvider to attach it at the same time Appyx Node is created.
    • #185Breaking change: Activity must implement IntegrationPointProvider and create IntegrationPoint manually. Weak references usage has been removed.
    • #173Breaking change: ActivityStarter and PermissionRequester now exposes coroutine based API instead of minimal.reactive.
    • #200Breaking change: Reordered the parameters for ParentNode<NavTarget>.Child and fun <N : Node> NodeHost to meet Compose guidelines.
    • #43Updated: Jetpack Compose to 1.2.1 and Kotlin to 1.7.10.
    • #168Updated: Kotlin coroutines to 1.6.4.
    • #171Updated: RIBs to 0.36.1.
    • #212Updated: Node parent property is now public instead of private.
    • #174Fixed: IntegrationPointExample does not work with "do not keep activities"
    • #180Added: Ensure that super.onSaveInstanceState() was called to restore Node's state correctly
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha09(Sep 22, 2022)

    • #151 - Breaking change: Renamed Routing to NavTarget. All related namings are affected (RoutingElement, RoutingKey, etc.)
    • #158 - Breaking change: Renamed TransitionState to State in all NavModel impls. Renamed STASHED_IN_BACK_STACK to STASHED.
    • #146 - Breaking change: Removed FragmentIntegrationPoint. Clients should use ActivityIntegrationPoint.getIntegrationPoint(context: Context) to get integration point from Fragment
    • #160 - Breaking change: Renamed navmodel-addons to navmodel-samples and stopped publishing the binary. If you feel we should add any of the samples to the main codebase, please let us know!
    • #138 - Fixed: androidx.appcompat:appcompat from is exposed via api within com.bumble.appyx:core. This prevents potential compilation bugs.
    • #143 - Fixed: Correctly exposed transitive dependencies that are part of the libraries ABI
    • #162 - Fixed: NodeTestHelper's moveTo function can now move to Lifecycle.State.DESTROYED. The node itself has safeguards to prevent moving from destroyed state, and moving to destroyed is a valid test case.
    • #145 - Updated: SpotlightSlider now uses offset modifier with lambda
    • #159 - Added: NodeHost now takes modifier parameter to decorate the view of a root node
    • #162 - Added: disposeOnDestroyPlugin extension has been added to interop-rx2. This will allow Rx2 code to be easily disposed when the node it belongs to is destroyed.
    • #161 - Added: Operation helpers
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha08(Sep 12, 2022)

    • #140 - Breaking change: Added testing-ui-activity module to avoid needing to add testing-ui as a debug implementation as part of instrumentation testing. See the linked issue for more details
    • #139 - Fixed: IntegrationPoint memory leak created by ActivityIntegrationPoint
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha07(Sep 9, 2022)

    • #122 - Breaking change: ChildEntry.ChildMode is removed, now nodes are always created when a nav model changes (previously default behaviour)
    • #99Breaking change: Removed IntegrationPointAppyxProvider and made ActivityIntegrationPoint's constructor private. Use ActivityIntegrationPoint.createIntegrationPoint. This uses a weak reference to keep track of the integration points, and will not introduce memory leaks.
    • #122 - Added: New ChildEntry.KeepMode that allows to destroy nodes that are currently not visible on the screen
    • #132 - Added: New NodeComponentActivity to extend when wanting to work with ComponentActivity as your base activity, eg when migrating from a project built from the Jetpack Compose template
    • #119 - Fixed: Lifecycle observers are invoked in incorrect order (child before parent)
    • #62 - Fixed: Node is marked with stable annotation making some of the composable functions skippable
    • #129 - Updated: Removed sealed interface from operations to allow client to define their own
    • #133 - Updated: NodeView interface and ParentNode marked as stable improving amount of skippable composables
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha06(Aug 26, 2022)

    • #96Breaking change: Removed InteractorTestHelper. Please use Node tests instead of Interactor tests.
    • #99Breaking change: Modified package of NodeConnector and Connectable
    • #99Added: Source.rx2() to convert Source to io.reactivex.Observable
    • #107Fixed: Back press handlers are not properly registered on lifecycle events
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha05(Aug 19, 2022)

    • https://github.com/bumble-tech/appyx/issues/83 – Breaking change: RoutingSource renamed to NavModel. All subclasses, fields, package names, etc., any mentions of the word follow suit.
    • https://github.com/bumble-tech/appyx/pull/91 – Fixed: Spotlight next and previous operations crash fix
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha04(Aug 18, 2022)

    • https://github.com/bumble-tech/appyx/pull/39 – Added: Workflows implementation to support deeplinks
    • https://github.com/bumble-tech/appyx/pull/32 – Added: BackPressHandler plugin that allows to control back press behaviour via androidx.activity.OnBackPressedCallback
    • https://github.com/bumble-tech/appyx/issues/59 – Added: interface for ParentNodeView<>
    • https://github.com/bumble-tech/appyx/issues/69 – Added: Jetpack Compose Navigation code sample
    • https://github.com/bumble-tech/appyx/issues/81 – Added: Support integration point for multiple roots
    • https://github.com/bumble-tech/appyx/pull/65 – Added: InteropBuilderStub and InteropSimpleBuilderStub testing util classes
    • https://github.com/bumble-tech/appyx/issues/47 – Updated: The customisations module is now pure Java/Kotlin.
    • https://github.com/bumble-tech/appyx/issues/85 – Updated: Improved InteropView error messaging when Activity does not implement IntegrationPointAppyxProvider
    • https://github.com/bumble-tech/appyx/issues/88 – Updated: Moved TestUpNavigationHandler to testing-unit-common
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha03(Aug 2, 2022)

  • 1.0-alpha02(Jul 19, 2022)

    • https://github.com/bumble-tech/appyx/pull/19 – Fixed: Do not allow setting Node.integrationPoint on non-root nodes.
    • https://github.com/bumble-tech/appyx/pull/21 – Fixed: Integration point attached twice crash when using live literals
    • https://github.com/bumble-tech/appyx/issues/14 – Fixed: Transition interruptions bug
    • https://github.com/bumble-tech/appyx/pull/23 – Added: Unit test support
    • https://github.com/bumble-tech/appyx/issues/26 – Added: Publish snapshot versions
    • https://github.com/bumble-tech/appyx/pull/9 – Migrated app-tree-utils into this repository
    Source code(tar.gz)
    Source code(zip)
  • 1.0-alpha01(Jul 4, 2022)

Compose-navigation - Set of utils to help with integrating Jetpack Compose and Jetpack's Navigation

Jetpack Compose Navigation Set of utils to help with integrating Jetpack Compose

Adam Kobus 5 Apr 5, 2022
A library that enables Safe Navigation for you Composable destinations when using Jetpack Compose Navigation

A library that enables Safe Navigation for you Composable destinations when using Jetpack Compose Navigation

Roman Levinzon 59 Oct 19, 2022
An MVI project setup using Jetpack compose. This would be a good place to start learning Model View Intent (MVI) architecture for Android.

Compose-MVI An MVI project setup using Jetpack compose. This would be a good place to start learning Model View Intent (MVI) architecture for Android.

null 6 Jul 28, 2022
Navigation-Compose - A sample to showcase Kotlin, MVVM, Hilt, Coroutines, StateFlow, Jetpack compose

Navigation-Compose A sample to showcase Kotlin, MVVM, Hilt, Coroutines, StateFlo

Mohammadali Rezaei 6 Jul 13, 2022
A Simple Blog App using Jetpack Compose, Flow, Navigation Compose, Room and Firebase

BlogCompose A Simple Blog App using Jetpack Compose, Flow, Navigation Compose, Room and Firebase Instructions Download your Firebase configuration fil

null 4 Oct 10, 2022
This repos one of the ways hows how to use Jetpack Compose Navigation along with Dagger 2

Dagger 2 and Jetpack Compose Integration This repository is about a way how to use Dagger 2 for projects which using Jetpack Compose. Here is an artic

Alexey Glukharev 10 Nov 16, 2022
Create Bottom Navigation Bar with Jetpack Compose

BottomNavigationBarComposeExample Create Bottom Navigation Bar with Jetpack Compose https://johncodeos.com/how-to-create-bottom-navigation-bar-with-je

JohnCodeos.com 31 Dec 24, 2022
Small Android project demonstrating some navigation components for Jetpack Compose.

Small Android project demonstrating some navigation components for Jetpack Compose. Created this for presenting about this topic for a GDG meetup.

Parshav 3 Sep 15, 2021
Small code generating library for safe Jetpack Compose navigation with no boilerplate.

Compose Destinations A KSP library to use alongside compose navigation. It reduces boilerplate code and is less error-prone since passing arguments be

Rafael Costa 1.9k Jan 5, 2023
Kotlin, MVVM, Navigation Component, Hilt, Jetpack Compose, Retrofit2

What is this project? This course will replace my old java mvvm introduction: https://codingwithmitch.com/courses/rest-api-mvvm-retrofit2/. Watch the

Mitch Tabian 452 Jan 1, 2023
[Tutorial] D-pad navigation in Jetpack Compose

dpad-compose D-pad navigation in Jetpack Compose The problem While Android is mostly used on touch devices, the operating system can also be used with

Walter Berggren 34 Nov 4, 2022
Android Sample Kotlin+ MVI + Jetpack compose + Coroutines + Retrofit + Hilt + Room + Navigation component

MVIComposeSample Android Sample app to show user latest movies implementing MVI + Clean Architecture using kotlin & Jetpack compose following solid an

Ahmed Atwa 10 Dec 28, 2022
Android App made by Jetpack Compose Components with Kotlin, MVVM Pattern, Multi Module, Navigation, Hilt, Coroutines, Retrofit and cached data by Room

Android App made by Jetpack Compose Components with Kotlin, MVVM Pattern, Multi Module, Navigation, Hilt, Coroutines, Retrofit and cached data by Room

Yogi Dewansyah 13 Aug 31, 2022
Android App made by Jetpack Compose Components with Kotlin, MVVM Pattern, Multi Module, Navigation, Hilt, Coroutines, Retrofit and cached data by Room

Mobile Banking Android App made by Jetpack Compose Components with Kotlin, MVVM Pattern, Multi Module, Navigation, Hilt, Coroutines, Retrofit and cach

Yogi Dewansyah 13 Aug 31, 2022
Jetpack Compose Boids | Flocking Insect 🐜. bird or Fish simulation using Jetpack Compose Desktop 🚀, using Canvas API 🎨

?? ?? ?? Compose flocking Ants(boids) ?? ?? ?? Jetpack compose Boids | Flocking Insect. bird or Fish simulation using Jetpack Compose Desktop ?? , usi

Chetan Gupta 38 Sep 25, 2022
A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook or play-ground if you want!

Why Not Compose! A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook or play-ground if you want!

Md. Mahmudul Hasan Shohag 186 Jan 1, 2023
Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Compose for Android App Development. Android’s modern toolkit for building native UI.

Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Compose for Android App Development. Android’s modern toolkit for building native UI.

MindOrks 382 Jan 5, 2023
This is a sample app(For beginners - App #2) built using Jetpack Compose. It demonstrates the concept of State Hoisting in Jetpack Compose.

JetBMICalculator This is a sample app(For beginners - App #2) built using Jetpack Compose. It demonstrates the concept of State Hoisting in Jetpack Co

BHAVNA THACKER 3 Dec 31, 2022
Jetpack-Compose-Demo - Instagram Profile UI using Jetpack Compose

Jetpack-Compose-Demo Instagram Profile UI using Jetpack Compose

omar 1 Aug 11, 2022