All Projects → marcellogalhardo → retained

marcellogalhardo / retained

Licence: Apache-2.0 license
[ACTIVE] A lightweight alternative to Android's ViewModels. The easiest way to retain instances in Activities, Fragments or Composables.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to retained

xlsx-renderer
Render xlsx from template
Stars: ✭ 21 (-91.63%)
Mutual labels:  viewmodel
StarWarsSearch-MVI
Star wars sample android project showcasing the use of View components for rendering UI in Fragments and Activities. Uses Android Jetpack, clean architecture with MVI (Uni-directional data flow), dagger hilt, and kotlin coroutines with StateFlow
Stars: ✭ 189 (-24.7%)
Mutual labels:  viewmodel
Sunset-hadith
Islamic app written with Kotlin, using KTOR + coroutines + flow + MVVM + Android Jetpack + Navigation component. Old version using RxJava + Retrofit + OKHttp
Stars: ✭ 26 (-89.64%)
Mutual labels:  viewmodel
MultiplatformPlayground
Kotlin Multiplatform project in Jetpack Compose & SwiftUI with shared ViewModel layer and File upload
Stars: ✭ 72 (-71.31%)
Mutual labels:  viewmodel
Pursuit-Core-Android
Pursuit Core Android
Stars: ✭ 45 (-82.07%)
Mutual labels:  viewmodel
Witch-Android
View-data binding library for Android.
Stars: ✭ 25 (-90.04%)
Mutual labels:  viewmodel
Delish
Delish, a Food Recipes App in Jetpack Compose and Hilt based on modern Android tech-stacks and MVI clean architecture.
Stars: ✭ 356 (+41.83%)
Mutual labels:  viewmodel
Newsster
Android App using Paging3, Hilt, Coroutines, Flow, Jetpack, MVVM architecture.
Stars: ✭ 147 (-41.43%)
Mutual labels:  viewmodel
KotlinEverywhere
This application created for Kotlin Everywhere series as a codelab. It will show step by step Kotlin and Android Jetpack Components fundamentals. 🚀🚀
Stars: ✭ 52 (-79.28%)
Mutual labels:  viewmodel
Clean-MVVM-NewsApp
Android News app developed using Clean + MVVM architecture
Stars: ✭ 52 (-79.28%)
Mutual labels:  viewmodel
MvvmBlazor
A lightweight Blazor Mvvm Library
Stars: ✭ 203 (-19.12%)
Mutual labels:  viewmodel
ReactiveLiveData
An RxJava Extension for the LiveData observer introduced by Google.
Stars: ✭ 17 (-93.23%)
Mutual labels:  viewmodel
Compose-ToDo
A fully functional Android TODO app built entirely with Kotlin and Jetpack Compose
Stars: ✭ 130 (-48.21%)
Mutual labels:  viewmodel
roove
Dating app based on firebase services and facebook login. MVVM-Kotlin-RxJava-Dagger-Databinding
Stars: ✭ 55 (-78.09%)
Mutual labels:  viewmodel
KTAndroidArchitecture
A Kotlin android architecture with Google Architecture Components
Stars: ✭ 33 (-86.85%)
Mutual labels:  viewmodel
TeamManagerApp
A sample app structure using the MVVM architecture LiveData, RxJava, ViewModel, Room and the Navigation Arch Components.
Stars: ✭ 36 (-85.66%)
Mutual labels:  viewmodel
floppy
🧩 Handling and maintain your UI view component easily
Stars: ✭ 55 (-78.09%)
Mutual labels:  viewmodel
node-viewmodel
Node-viewmodel is a node.js module for multiple databases. It can be very useful if you work with (d)ddd, cqrs, eventdenormalizer, host, etc.
Stars: ✭ 29 (-88.45%)
Mutual labels:  viewmodel
Chat-App-Android
Chat app based on the MVVM architecture using Kotlin, ViewModel, LiveData, DataBinding and more.
Stars: ✭ 70 (-72.11%)
Mutual labels:  viewmodel
AndroidDaggerSample
Android-dagger and Architecture component ViewModel sample
Stars: ✭ 30 (-88.05%)
Mutual labels:  viewmodel

Retained Instance

A lightweight library built on top of Android Architecture Component ViewModel to simplify how UI Controllers (e.g., Activity, Fragment & NavBackStackEntry) retain instances on Android.

  • Eliminate ViewModel inheritance.
  • Eliminate ViewModelProvider.Factory need.
  • Easy access to ViewModel scoped properties: CoroutineScope (viewModelScope), SavedStateHandle, and many others.
  • Enable composition: callbacks can be listened with OnClearedListener.

Motivation: Retained was originally created to share a ViewModel in Kotlin Multiplatform projects between Android & iOS with ease.

Download

dependencies {
    // `Activity` support
    implementation 'dev.marcellogalhardo:retained-activity:{Tag}'

    // `Fragment` support, includes `Activity` support
    implementation 'dev.marcellogalhardo:retained-fragment:{Tag}'

    // Navigation support
    implementation 'dev.marcellogalhardo:retained-navigation:{Tag}'

    // Navigation with Fragment support, includes `Navigation` support
    implementation 'dev.marcellogalhardo:retained-navigation-fragment:{Tag}'
}

(Please replace {Tag} with the latest version numbers)

Usage

The following sections demonstrate how to retain instances in activities and fragments. For simplicity, all examples will retain the following class:

class ViewModel(var counter: Int = 0)

Use Retained in Activities and Fragments

// retain an instance in an Activity:
class CounterActivity : AppCompatActivity() {
    private val viewModel: ViewModel by retain { ViewModel() }
}

// retain an instance in a Fragment:
class CounterFragment : Fragment() {
    private val viewModel: ViewModel by retain { ViewModel() }
}

// share an instance between Fragments scoped to the Activity
class CounterFragment : Fragment() {
    private val sharedViewModel: ViewModel by retainInActivity { ViewModel() }
}

// share an instance between Fragments scoped to the NavGraph
class CounterFragment : Fragment() {
    private val viewModel: ViewModel by retainInNavGraph(R.navigation.nav_graph) { ViewModel() }
}

Use Retained in Compose

@Composable
fun SampleView() {
    // Using an Activity
    val activity: ComponentActivity // find Activity
    val viewModel by activity.retain { ViewModel() }

    // Using a Fragment
    val fragment: Fragment // find Fragment
    val viewModel by fragment.retain { ViewModel() }

    // Using NavBackStackEntry
    val navBackStackEntry: NavBackStackEntry // find NavBackStackEntry
    val viewModel by navBackStackEntry.retain { ViewModel() }
}

Advanced usage

Custom parameters from Jetpack's ViewModel

When retaining an instance, you have access to a RetainedEntry which contains all parameters you might need.

@Composable
fun SampleView() {
    val viewModel = retain { entry: RetainedEntry ->
        ViewModel()
    }
    // ...
}

The entry exposes a SavedStateHandle that can be used to work with the saved state, just like in a regular Android ViewModel.

class CounterFragment : Fragment() {
    private val viewModel: ViewModel by retain { entry -> 
        ViewModel(counter = entry.savedStateHandle.get<Int>("count"))
    }
    // ...
}

It also exposes a CoroutineScope that works just like viewModelScope from the Android ViewModel.

class Presenter(scope: CoroutineScope) { /* ... */ }

fun SampleFragment() {
    private val presenter: Presenter by retain { entry -> 
        Presenter(scope = entry.scope)
    }
    // ...
}

For more details, see RetainedEntry.

Listening onCleared calls

When retaining an instance, you can use the RetainedEntry to be notified when a retained instance is cleared (ViewModel.onCleared).

@Composable
fun SampleView() {
    val viewModel by retain { entry ->
        entry.onClearedListeners += {
            println("Invoked when the host 'ViewModel.onCleared' is called")
        }
    }
    // ...
}

As a convenience, if the retained instance implements the OnClearedListener interface, it will be automatically added to onClearedListeners and notified.

View support (Experimental)

Besides Activities and Fragments, it's also possible to retain instances in a view. There are a couple of extra modules for that:

dependencies {
    implementation 'dev.marcellogalhardo:retained-view:{Tag}'
    implementation 'dev.marcellogalhardo:retained-navigation-view:{Tag}'
}

The retained-view module exposes retainInActivity and retain, which will scope the instance to the parent being it an activity or a fragment. The retained-view-navigation module exposes retainInNavGraph to retain instances scoped to the NavGraph.

License

Copyright 2019 Marcello Galhardo

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].