# StateFlow

Published articles for StateFlow.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Kotlin Explicit Backing Fields: Encapsulation Tradeoffs and Downcasting Risks

DevFeed: [Kotlin Explicit Backing Fields: Encapsulation Tradeoffs and Downcasting Risks](<https://devfeed.tech/articles/the-downcast-trap-in-kotlin-s-explicit-backing-fields-22951.md>)

Original publisher: [Read original article](<https://proandroiddev.com/the-downcast-trap-in-kotlins-explicit-backing-fields-626ef0d66e50?source=rss----c72404660798---4>)

Author: Ehab Elwan

Published: 2026-09-13T05:31:32Z

Content type: opinion

Language: en

Sources: [ProAndroidDev - Medium](<https://devfeed.tech/sources/proandroiddev-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [article](<https://devfeed.tech/tags/article.md>), [clean-code](<https://devfeed.tech/tags/clean-code.md>), [code](<https://devfeed.tech/tags/code.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [memory](<https://devfeed.tech/tags/memory.md>), [software-architecture](<https://devfeed.tech/tags/software-architecture.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>)

### AI overview

This article compares Kotlin's traditional private mutable property plus public read-only wrapper with explicit backing fields. It explains that explicit backing fields can avoid an extra wrapper allocation, but because the underlying object remains mutable, an external downcast may bypass the intended read-only restriction and mutate internal state.

### Source excerpt

Why eliminating the double-property boilerplate changes how we protect our architecture Image generated by AIDisclosure: This article was drafted by me and refined with the help of AI tools. If you have written Kotlin in the last few years, you are intimately familiar with the double-property boilerplate. Whether in Android ViewModels or general state holders, maintaining a private mutable property alongside a public read-only property is a chore we have all accepted in the name of strict encapsulation to prevent our internal state from being hijacked by outside classes. It makes the code significantly cleaner (and slightly more memory efficient). However, it fundamentally changes how we protect our state, moving from a physical object boundary to a simple type restriction. Let's look at the tradeoff. The Old Way: Wrapper Protection For years, the standard approach to encapsulating state has looked like this: class OldViewModel { // 1. The private mutable state private val _uiState = MutableStateFlow(UiState()) // 2. The public read-only state val uiState: StateFlow<UiState> = _uiState.asStateFlow() } This is tedious to write, but it provides a strict architectural guarantee. When you call .asStateFlow(), Kotlin does not just change the type; it creates a brand new wrapper object in memory (ReadonlyStateFlow). While this physical barrier is fantastic for safety, it does mean you are incurring a minor memory allocation overhead by creating a secondary wrapper object for every exposed state. The New Way: Upcasting Explicit Backing Fields allow you to merge these two properties into one concise declaration, bypassing that extra memory allocation entirely: class NewViewModel { val uiState: StateFlow<UiState> field = MutableStateFlow(UiState()) } Inside your class, the Kotlin compiler smart-casts the field so you can mutate it internally. Outside the class, the compiler restricts callers to the read-only StateFlow interface. It looks incredibly clean and saves an allocat

## How to Prevent Race Conditions in Coroutines

DevFeed: [How to Prevent Race Conditions in Coroutines](<https://devfeed.tech/articles/how-to-prevent-race-conditions-in-coroutines-25006.md>)

Original publisher: [Read original article](<https://typealias.com/articles/prevent-race-conditions-in-coroutines/>)

Author: author@typealias.com (Dave Leeds)

Published: 2025-11-24T00:00:00Z

Content type: tutorial

Language: en

Sources: [Dave Leeds on Kotlin - typealias.com](<https://devfeed.tech/sources/dave-leeds-on-kotlin-typealias-com.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>)

Tags: [actor](<https://devfeed.tech/tags/actor.md>), [atomicint](<https://devfeed.tech/tags/atomicint.md>), [atomics](<https://devfeed.tech/tags/atomics.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [limitedparallelism](<https://devfeed.tech/tags/limitedparallelism.md>), [mutex](<https://devfeed.tech/tags/mutex.md>), [programming](<https://devfeed.tech/tags/programming.md>), [race-condition](<https://devfeed.tech/tags/race-condition.md>), [shared-mutable-state](<https://devfeed.tech/tags/shared-mutable-state.md>), [state](<https://devfeed.tech/tags/state.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [structured-concurrency](<https://devfeed.tech/tags/structured-concurrency.md>)

### AI overview

This tutorial explains that Kotlin coroutines and structured concurrency do not automatically protect shared mutable state from race conditions. It introduces the issue using an example that creates 100,000 random bakery orders.

### Source excerpt

Thanks to structured concurrency, there are a lot of concerns that we don't have to handle manually when working with Kotlin coroutines. For example, parent coroutines automatically wait for their children to complete before completing themselves. And when a parent coroutine is cancelled, its children are automatically cancelled, too. But when it comes to shared mutable state - mutable data that multiple coroutines could update at the same time - there's nothing magical in the design of coroutines to ensure that the state is updated properly.

## Android ViewModel Data Loading: Best Practices and Flow-Based Architecture

DevFeed: [Android ViewModel Data Loading: Best Practices and Flow-Based Architecture](<https://devfeed.tech/articles/android-viewmodel-data-loading-best-practices-and-flow-based-architecture-22967.md>)

Original publisher: [Read original article](<https://funkymuse.github.io/posts/properly-load-data/>)

Author: FunkyMuse

Published: 2025-08-28T23:11:00Z

Content type: opinion

Language: en

Sources: [FunkyMuse](<https://devfeed.tech/sources/funkymuse.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Development](<https://devfeed.tech/topics/development.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [compose](<https://devfeed.tech/tags/compose.md>), [development](<https://devfeed.tech/tags/development.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [mvi](<https://devfeed.tech/tags/mvi.md>), [mvvm](<https://devfeed.tech/tags/mvvm.md>), [patterns](<https://devfeed.tech/tags/patterns.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

An opinionated Android architecture article examines data-loading patterns in ViewModels and discusses problems associated with loading data in initialization blocks, including re-entry behavior, dispatcher timing, data freshness, and testability. It presents Kotlin Flow and StateFlow sharing as the proposed solution.

### Source excerpt

Architecture discussions in Android development often spark passionate debates--sometimes garnering both praise and criticism. Writing about these topics isn't easy, but that's what makes it worthwhile. This article presents my opinionated perspective on data loading patterns, refined through experience and recovery from recent surgeries (one recovery is still in progress). Consider this a sna...

## Bridging Compose and View: Seamless Interop Communication with CompositionLocal

DevFeed: [Bridging Compose and View: Seamless Interop Communication with CompositionLocal](<https://devfeed.tech/articles/bridging-compose-and-view-seamless-interop-communication-with-compositionlocal-25937.md>)

Original publisher: [Read original article](<https://juliensalvi.medium.com/bridging-compose-and-view-seamless-interop-communication-with-compositionlocal-4b0a273bf15f?source=rss-cbfc736ddcd3------2>)

Author: Julien Salvi

Published: 2025-03-05T13:42:13Z

Content type: tutorial

Language: en

Sources: [Stories by Julien Salvi on Medium](<https://devfeed.tech/sources/stories-by-julien-salvi-on-medium.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [interoperability](<https://devfeed.tech/topics/interoperability.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [bridge](<https://devfeed.tech/tags/bridge.md>), [compose](<https://devfeed.tech/tags/compose.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [interface-implementation](<https://devfeed.tech/tags/interface-implementation.md>), [interoperability](<https://devfeed.tech/tags/interoperability.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to bridge Jetpack Compose and traditional Android Views using CompositionLocal. It shows how to provide a FeedbackMessageInterop implementation so composables can trigger View-based feedback, and describes the reverse direction through an interface and reactive streams such as StateFlow or SharedFlow.

### Source excerpt

Migrating to Compose exposed the team to several interoperability challenges as we integrated new Composables into our existing codebase. One key hurdle was figuring out how to trigger events from Compose and dispatch them to the main View holder, such as a Fragment or Activity. After some exploration, we found an efficient solution using CompositionLocal. Here's how we made it work! 🚀 What is a CompositionLocal? Think of CompositionLocal as a localized dependency injection system built directly into Compose's composition model. You create a CompositionLocal instance, which acts as a key for a specific type of data. Then, using the CompositionLocalProvider, you define a scope within your UI tree and associate a value with that CompositionLocal key. Any composable within that scope can then access the provided value using the CompositionLocal.current property, without needing to know where the value originated. This not only simplifies code but also makes it more maintainable and reusable. Furthermore, CompositionLocal values can be dynamic, triggering recomposition when they change, and they are thread-safe, making them a powerful tool for managing shared state within your Compose UI. Interop Communication with CompositionLocal In the following code, LocalFeedbackInterop is a staticCompositionLocalOf that will hold an implementation of the FeedbackMessageInterop interface. This interface defines the methods for showing feedback alerts, and the staticCompositionLocalOf ensures that the implementation is unlikely to change as it cannot be re-provided. This allows any composable within the scope to access the FeedbackMessageInterop implementation and trigger feedback messages without explicit dependencies. import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf val LocalFeedbackInterop: ProvidableCompositionLocal<FeedbackMessageInterop?> = staticCompositionLocalOf { null } interface FeedbackMessageInterop { fu

## Representing ViewModel events with StateFlow vs. SharedFlow vs. Channel

DevFeed: [Representing ViewModel events with StateFlow vs. SharedFlow vs. Channel](<https://devfeed.tech/articles/representing-viewmodel-events-with-stateflow-vs-sharedflow-vs-channel-39393.md>)

Original publisher: [Read original article](<https://kt.academy/article/viewmodel-stateflow-sharedflow-channel>)

Published: 2024-11-18T00:00:00Z

Content type: tutorial

Language: en

Sources: [Kt. Academy](<https://devfeed.tech/sources/kt-academy.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [channel](<https://devfeed.tech/tags/channel.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [toast](<https://devfeed.tech/tags/toast.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

This article compares StateFlow, SharedFlow, and Channel for representing events in an Android ViewModel. It explains why StateFlow can lose events, notes SharedFlow's behavior when no UI observer is present, and discusses using an unlimited-capacity Channel as an event queue.

### Source excerpt

What is the best way to represent ViewModel events in Kotlin?

## Coroutine Testing - Never ending tests & backgroundScope

DevFeed: [Coroutine Testing - Never ending tests & backgroundScope](<https://devfeed.tech/articles/coroutine-testing-never-ending-tests-backgroundscope-25236.md>)

Original publisher: [Read original article](<https://kau.sh/blog/coroutine-testing-backgroundscope/>)

Author: Kaushik Gopal

Published: 2024-08-30T07:00:45Z

Content type: tutorial

Language: en

Sources: [Kaushik Gopal's Site](<https://devfeed.tech/sources/kaushik-gopal-s-site.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Unit testing](<https://devfeed.tech/topics/unit-testing.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Android](<https://devfeed.tech/topics/android.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [channel](<https://devfeed.tech/tags/channel.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutine-testing](<https://devfeed.tech/tags/coroutine-testing.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [job](<https://devfeed.tech/tags/job.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>), [unit-testing](<https://devfeed.tech/tags/unit-testing.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains why coroutine tests can time out when they collect from non-terminating Channels, SharedFlow, StateFlow, or ViewModel jobs. It presents manual Job cancellation and backgroundScope, which cancels child coroutines when the test body completes.

### Source excerpt

series This is part of a series of posts on Coroutine Testing: Picking the right Dispatcher Never ending tests & backgroundscope <- Controlling time Helpful @Junit TestRule extension (coming soon) Full USF example for Android (coming soon) If you've spent some time testing Coroutines this exception should look familiar: After waiting for 1m, the test coroutine is not completing, there were active child jobs This tends to happen when you have a coroutine job in your test, that fails to complete on its own. Let's take a simple example. src on github We use a Channel here which is the proverbial event bus for Coroutines. source: kotlinlang.org Channels don't terminate on their own. So when you run a simple test checking the emission, while the items might get collected correctly per the assert statement in the test, the test itself fails like so: test on github The test here is waiting for that coroutine job to complete, which in turn requires the Channel to, but that never happens and the test times out. Where else would I run into this problem? # Channels aren't the only case you'll run into this problem. For example if you use a "hot" Flow like SharedFlow or StateFlow, they don't terminate on their own, so the onus is on you to complete or cancel their Job in tests. Android developers can frequently run into this problem too if you use ViewModels and have an internal StateFlow providing your "view level data" (what i personally like to call "view state"). You typically use the viewModelScope to launch internal coroutine jobs in a ViewModel. The OS then calls the lifecycle method onClear when the Activity or Fragment no longer needs the ViewModel where all jobs started in the viewModelScope are canceled. But when unit testing these ViewModels, you don't have access to the viewModelScope and shouldn't need it anyway. Solving this problem # There's two ways to solve this problem: 1. Manually cancel the Job ## If you have access to the Job that spawns the never-ending co

## SharedFlow vs StateFlow

DevFeed: [SharedFlow vs StateFlow](<https://devfeed.tech/articles/sharedflow-vs-stateflow-39374.md>)

Original publisher: [Read original article](<https://kt.academy/article/sharedflow_vs_stateflow>)

Published: 2024-06-27T00:00:00Z

Content type: tutorial

Language: en

Sources: [Kt. Academy](<https://devfeed.tech/sources/kt-academy.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [LineageOS](<https://devfeed.tech/topics/lineageos.md>), [Back end](<https://devfeed.tech/topics/backend.md>), [WebSocket](<https://devfeed.tech/topics/websocket.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [backend](<https://devfeed.tech/tags/backend.md>), [exceptions](<https://devfeed.tech/tags/exceptions.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [messages](<https://devfeed.tech/tags/messages.md>), [parameter](<https://devfeed.tech/tags/parameter.md>), [progress](<https://devfeed.tech/tags/progress.md>), [service](<https://devfeed.tech/tags/service.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [state](<https://devfeed.tech/tags/state.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [users](<https://devfeed.tech/tags/users.md>), [value](<https://devfeed.tech/tags/value.md>), [websocket](<https://devfeed.tech/tags/websocket.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

This tutorial explains the distinction between Kotlin's StateFlow and SharedFlow. StateFlow represents observable application state, while SharedFlow broadcasts events to observers. It discusses replay, required initial values, distinct updates, conflation, and examples for Android and backend services.

### Source excerpt

When to use SharedFlow and when to use StateFlow.

## Kotlin var with Read-Only Collections vs. val with Mutable Collections

DevFeed: [Kotlin var with Read-Only Collections vs. val with Mutable Collections](<https://devfeed.tech/articles/mutable-objects-or-properties-39391.md>)

Original publisher: [Read original article](<https://kt.academy/article/var_readonly_vs_val_mutable>)

Published: 2024-06-03T00:00:00Z

Content type: tutorial

Language: en

Sources: [Kt. Academy](<https://devfeed.tech/sources/kt-academy.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Collections](<https://devfeed.tech/topics/collections.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [bugs](<https://devfeed.tech/tags/bugs.md>), [collections](<https://devfeed.tech/tags/collections.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [memory](<https://devfeed.tech/tags/memory.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

This article compares Kotlin var properties holding read-only collections with val properties holding mutable collections. It explains trade-offs involving copying costs, observability, defensive copies, and thread safety, concluding that the preferable choice depends on how the state is accessed and modified.

### Source excerpt

Time to answer the question: var/readonly vs val/mutable. Which one should you use?

## The conflation problem of testing StateFlows

DevFeed: [The conflation problem of testing StateFlows](<https://devfeed.tech/articles/the-conflation-problem-of-testing-stateflows-27057.md>)

Original publisher: [Read original article](<https://zsmb.co/conflating-stateflows/>)

Author: Márton Braun

Published: 2023-08-15T14:00:00Z

Content type: tutorial

Language: en

Sources: [zsmb.co](<https://devfeed.tech/sources/zsmb-co.md>)

Topics: [Testing](<https://devfeed.tech/topics/testing.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [coroutine-testing](<https://devfeed.tech/tags/coroutine-testing.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlinx](<https://devfeed.tech/tags/kotlinx.md>), [marton-braun](<https://devfeed.tech/tags/marton-braun.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [zsmb](<https://devfeed.tech/tags/zsmb.md>), [zsmb-co](<https://devfeed.tech/tags/zsmb-co.md>), [zsmb13](<https://devfeed.tech/tags/zsmb13.md>), [zsmbco](<https://devfeed.tech/tags/zsmbco.md>)

### AI overview

This article explains how StateFlow conflation affects tests. It compares asserting on the StateFlow state property with collecting emitted values, and discusses testing intermediate values when rapid updates may be skipped by slow collectors.

### Source excerpt

StateFlow behaves as a state holder and a Flow of values at the same time. Due to conflation, a collector of a StateFlow might not receive all values that it holds over time. This article covers what that means for your tests.

## Context Receivers in Kotlin: An Example

DevFeed: [Context Receivers in Kotlin: An Example](<https://devfeed.tech/articles/context-receivers-in-kotlin-an-example-25676.md>)

Original publisher: [Read original article](<https://blog.sanskar10100.dev/context-receivers-in-kotlin-an-example>)

Author: Sanskar Agrawal

Published: 2023-02-26T16:21:57Z

Content type: tutorial

Language: en

Sources: [Sanskar's Stuff](<https://devfeed.tech/sources/sanskar-s-stuff.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [coding](<https://devfeed.tech/topics/coding.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial introduces Kotlin context receivers, a feature added in Kotlin 1.6.20, and explains their use through comparison with extension functions. It focuses on simplifying code that combines a StateFlow receiver with lifecycle-related context when collecting reactive UI state. The supplied text ends before the example is complete.

### Source excerpt

Context Receivers are a new feature introduced in Kotlin 1.6.20. They're useful for receiving the context from the call-site when a function is called. To understand it and its utility, let's first take a look at a similar feature available in the la...

## StateFlow and SharedFlow in ViewModels

DevFeed: [StateFlow and SharedFlow in ViewModels](<https://devfeed.tech/articles/stateflow-and-sharedflow-in-viewmodels-22664.md>)

Original publisher: [Read original article](<https://www.valueof.io/blog/stateflow-sharedflow-flow-viewmodel-lifecycle>)

Author: James Shvarts

Published: 2022-12-28T19:21:19Z

Content type: tutorial

Language: en

Sources: [Android Blog - Mobile Dev Notes](<https://devfeed.tech/sources/android-blog-mobile-dev-notes.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [Code](<https://devfeed.tech/topics/code.md>), [Unit testing](<https://devfeed.tech/topics/unit-testing.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compose](<https://devfeed.tech/tags/compose.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [unit-testing](<https://devfeed.tech/tags/unit-testing.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A practical guide to choosing between StateFlow and SharedFlow in Android ViewModels. It covers lifecycle-aware collection, exposing flows as UI state in view-based apps and Compose, and unit testing ViewModels that convert flows into state or shared events.

### Source excerpt

Collecting State and Shared Flows from ViewModels while respecting lifecycle of the collector views

## Consuming flows safely in Jetpack Compose

DevFeed: [Consuming flows safely in Jetpack Compose](<https://devfeed.tech/articles/consuming-flows-safely-in-jetpack-compose-35672.md>)

Original publisher: [Read original article](<https://manuelvivo.dev/consuming-flows-compose>)

Author: Manuel Vivo

Published: 2022-08-10T00:00:00Z

Content type: tutorial

Language: en

Sources: [Manuel Vivo .dev](<https://devfeed.tech/sources/manuel-vivo-dev.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [API](<https://devfeed.tech/topics/api.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [function](<https://devfeed.tech/topics/function.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Boilerplate](<https://devfeed.tech/topics/boilerplate.md>), [now-in-android](<https://devfeed.tech/topics/now-in-android.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [boilerplate](<https://devfeed.tech/tags/boilerplate.md>), [compose](<https://devfeed.tech/tags/compose.md>), [flow](<https://devfeed.tech/tags/flow.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [now-in-android](<https://devfeed.tech/tags/now-in-android.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to use collectAsStateWithLifecycle in Jetpack Compose to collect Flow and StateFlow values from UI code in a lifecycle-aware way. It describes how collection follows the app lifecycle, stops by default when the app is in the background, and helps avoid unnecessary resource usage. The API is identified as alpha and requires opting in to its annotation.

### Source excerpt

Use the collectAsStateWithLifecycle API to collect flows in a lifecycle-aware manner from your UI.

## Combining StateFlows and transforming it into a StateFlow

DevFeed: [Combining StateFlows and transforming it into a StateFlow](<https://devfeed.tech/articles/combining-stateflows-and-transforming-it-into-a-stateflow-25707.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/combining-stateflows-and-transforming-it-into-a-stateflow/>)

Author: Shreyas Patil

Published: 2022-06-24T12:30:00Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [multithreading](<https://devfeed.tech/tags/multithreading.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>)

### AI overview

A Kotlin tutorial about combining multiple StateFlows into a derived StateFlow. It explains limitations of existing Flow-combining approaches, including conversion requirements such as a scope and separately calculated initial state.

### Source excerpt

Master the art of combining multiple StateFlows into a single transformed StateFlow. Explore utilities and best practices for managing complex states in Kotlin.

## Kotlin Flow Notes: Producers, Consumers, Operators, and Hot and Cold Flows

DevFeed: [Kotlin Flow Notes: Producers, Consumers, Operators, and Hot and Cold Flows](<https://devfeed.tech/articles/flow-notes-32051.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/flow-notes/>)

Published: 2022-04-27T16:16:06Z

Content type: tutorial

Language: en

Sources: [maiatoday](<https://devfeed.tech/sources/maiatoday.md>)

Topics: [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Large Screen](<https://devfeed.tech/topics/large-screen.md>), [Streams](<https://devfeed.tech/topics/streams.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [article](<https://devfeed.tech/tags/article.md>), [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [cheat-sheet](<https://devfeed.tech/tags/cheat-sheet.md>), [code](<https://devfeed.tech/tags/code.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [coroutines-flow](<https://devfeed.tech/tags/coroutines-flow.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [sketch-note](<https://devfeed.tech/tags/sketch-note.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [streams](<https://devfeed.tech/tags/streams.md>)

### AI overview

A set of companion sketch notes about Kotlin Flow, covering suspend functions, streams of multiple values, producers and consumers, terminal and transform operators, execution contexts, hot and cold flows, and Android usage.

### Source excerpt

This post is my companion sketch notes for all the resources I consumed on the topic of flows. It is not meant to replace the info that I found on the internet but rather supplement it. Nor is it complete or should it be a standalone guide. In fact you can find an excellent list of my favourite resources at the end of the article. It is a document that helps me make sense of the topic. With that disclaimer out of the way... Let's take a step back and look at the suspend function. If your coroutine knowledge is rusty, freshen that up first. What if we want to provide multiple values? A stream of values that can be observed? Enter flows. At their most basic, flows have a producer and a consumer. The interface looks like this (spoiler it's just suspend functions under the hood) The consumer gets the multiple values by using a terminal operator. If I need to change the produced values along the way before consuming them, there are transform operators. How do I switch from main to io context? What's with the hot and cold flows? How do I remember which is which? Some practical hot flows. Flows on Android References Kotlin Coroutines Flow in a nutshell Kotlin Flows ~ an Android cheat sheet Kotlin Flows in Android summary Android flow Asynchronous Flow | Kotlin Flow under the hood: how does it really work KotlinConf 2019: Asynchronous Data Streams with Kotlin Flow by Roman Elizarov Kotlin Flows in a Nutshell FlowMarbles Android StateFlow and SharedFlow If you are reading this far I will reward you with an Android portait.

## SharedFlow and StateFlow

DevFeed: [SharedFlow and StateFlow](<https://devfeed.tech/articles/sharedflow-and-stateflow-39238.md>)

Original publisher: [Read original article](<https://kt.academy/article/cc-sharedflow-stateflow>)

Published: 2022-02-21T00:00:00Z

Content type: tutorial

Language: en

Sources: [Kt. Academy](<https://devfeed.tech/sources/kt-academy.md>)

Topics: [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>)

Tags: [channel](<https://devfeed.tech/tags/channel.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [scope](<https://devfeed.tech/tags/scope.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [value](<https://devfeed.tech/tags/value.md>), [values](<https://devfeed.tech/tags/values.md>), [workshop-learning-programming](<https://devfeed.tech/tags/workshop-learning-programming.md>)

### AI overview

A tutorial explaining Kotlin's SharedFlow and StateFlow for broadcasting and observing values among multiple coroutines. It covers replayed values, cancellation, interfaces for collecting and emitting, and converting a Flow with shareIn.

### Source excerpt

Known as a replacement for Subject, LiveData, and many more. SharedFlow and StateFlow are powerful coroutines classes, every Kotlin developer should know.

## Safely collecting hot flows from Android native UI

DevFeed: [Safely collecting hot flows from Android native UI](<https://devfeed.tech/articles/safely-collecting-hot-flows-from-android-native-ui-25910.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/safely-collecting-hot-flows-from-android-native-ui-f22f645edb44?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-09-02T23:38:42Z

Content type: tutorial

Language: en

Sources: [Stories by Chao Zhang on Medium](<https://devfeed.tech/sources/stories-by-chao-zhang-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [XML](<https://devfeed.tech/topics/xml.md>), [data](<https://devfeed.tech/topics/data.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [bug](<https://devfeed.tech/tags/bug.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [flow](<https://devfeed.tech/tags/flow.md>), [issue](<https://devfeed.tech/tags/issue.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [native](<https://devfeed.tech/tags/native.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

This tutorial explains a common Android UI pitfall when collecting multiple hot flows in one coroutine. Because StateFlow never completes, a later collection may never execute; the article presents separate coroutines and flowWithLifecycle() as fixes.

### Source excerpt

Photo: Merlene Goulet from Unsplash Along with the coroutine adoption, StateFlowbecomes an alternative observable data holder for LiveDatasince StateFlowhas almost all the functionalities of LiveDatawithout the main thread confinment. On top of following the best practice of the safer way to collect flows from Android UI, this story covers another common pitfall in detail. Setup I would like to display 2 text views and 1 button: First text view: Display a number X. Second text view: Display X² reactively. Button: Upon click, increments the number X. Apologize for the Jetpack Compose fans, I am still going to define the layout in XML with ViewBinding. https://medium.com/media/b411ff48ddf74bafb4288a430f431a87/href The data structure can be defined in the ViewModel : https://medium.com/media/3d3b345797521dd3063498c538d0715c/href To subscribe to these flows in the activity, I would use lifecycleScope.launchX to collect them, just like collecting LiveData in the old days: https://medium.com/media/4db49b992c028c1be26235e17d232d49/hrefBug When I run the app, I am expecting to see that every time I click the button, both text views will be updated, the first one with the new X and the second one with the new X². Let's run the app and see! What is happening? Why is the second text view not showing X²? Cause Reading the documentation of StateFlow , there is an important piece of information: State flow never completes. From the implementation side, StateFlowImpl has a while(true) loop that does not exit normally. Since we are subscribing a hot flow sourceFlowin the coroutine, the subsequent operations inside the coroutine will not ever be executed. lifecycleScope.launchWhenResumed { viewModel.sourceFlow.collect { binding.sourceFlow.text = it.toString() // Execution stops here } viewModel.transformedFlow.collect { binding.transformedFlow.text = it.toString() } } Note that if the upstream flow does not complete, the downstream flow does not complete either. In our case, sinkFlo

## Input validation in Jetpack Compose

DevFeed: [Input validation in Jetpack Compose](<https://devfeed.tech/articles/input-validation-in-jetpack-compose-25897.md>)

Original publisher: [Read original article](<https://proandroiddev.com/input-validation-in-jetpack-compose-e99c18b44fe3?source=rss-56174fa84bcc------2>)

Author: Denys Rudenko

Published: 2021-08-22T16:42:02Z

Content type: tutorial

Language: en

Sources: [Stories by Denis Rudenko on Medium](<https://devfeed.tech/sources/stories-by-denis-rudenko-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Dagger](<https://devfeed.tech/topics/dagger.md>), [Processes](<https://devfeed.tech/topics/processes.md>), [User experience (UX)](<https://devfeed.tech/topics/ux.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [androiddevweekly](<https://devfeed.tech/tags/androiddevweekly.md>), [dagger](<https://devfeed.tech/tags/dagger.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [savedstatehandle](<https://devfeed.tech/tags/savedstatehandle.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ux](<https://devfeed.tech/tags/ux.md>), [validation](<https://devfeed.tech/tags/validation.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial demonstrates manual and automatic input validation in Jetpack Compose. It uses composables, ViewModels, Dagger Hilt, StateFlow, and savedStateHandle to preserve input state after process death, validate fields, control button state, and emit success or error events. It also discusses restoring focus and improving keyboard-related user experience.

### Source excerpt

This post will not only focus on manual & auto validation of TextField inputs, but also on how to provide a nice UX by handling process death, including highlighting the last focused field upon restoration. https://medium.com/media/7d776a0ec6ff89810e194adf54680973/hrefSetup We'll use composables, viewModels & Dagger Hilt in these samples. Part 1: InputWrapper Let's create a wrapper for inputs, so it can contain both input value and errorId, if there is a validation error. Class is parcelable, so we can save it inside savedStateHandle later. https://medium.com/media/6c74ba5b4f958d63646a819643b45620/hrefPart 2: ViewModel (simplified version)https://medium.com/media/39bf975a63461cd00f68b8360c6a8f6b/href We're getting a stateFlow from the savedStateHandle using .getStateFlow extension. Using savedStateHandle here allows us to retain the latest data after process death happens. You can also use getLiveData, it's a matter of personal preferences unless you plan to perform observable.switchMap/flatMapLatest type of operations, since there is a subtle difference between stateFlow & liveData in such scenarios described here & change proposal created. areInputsValid stateFlow is combining name & creditCardNumber flows into a single one. The results it returns depend on whether input fields are valid or not. It's invoked whenever there is new emition to name or creditCardNumber flows. We'll use it's value to control buttons enabled/disabled state in our composable. _events will be used for one time events emission to the view layer. ScreenEvent is a sealed class representing all of our one time events. onNameEntered & onCardNumberEntered will be invoked when user enters symbols inside the TextField. We find out whether the input is valid by using an InputValidator object. It's returning either a string resource id containing error message, or a null. Latter means that input is valid. We store the new value & errorId using: https://medium.com/media/d9ad9c61328481f3318c143e6daf3

## Welcome you are visitor number 12345

DevFeed: [Welcome you are visitor number 12345](<https://devfeed.tech/articles/welcome-you-are-visitor-number-12345-32085.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/welcome-you-are-visitor-number-12345/>)

Published: 2021-07-12T19:44:03Z

Content type: tutorial

Language: en

Sources: [maiatoday](<https://devfeed.tech/sources/maiatoday.md>)

Topics: [ui](<https://devfeed.tech/topics/ui.md>), [Code](<https://devfeed.tech/topics/code.md>), [navigation](<https://devfeed.tech/topics/navigation.md>)

Tags: [90s-website](<https://devfeed.tech/tags/90s-website.md>), [animate](<https://devfeed.tech/tags/animate.md>), [code](<https://devfeed.tech/tags/code.md>), [components](<https://devfeed.tech/tags/components.md>), [compose](<https://devfeed.tech/tags/compose.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [snippet](<https://devfeed.tech/tags/snippet.md>), [state](<https://devfeed.tech/tags/state.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [stateless](<https://devfeed.tech/tags/stateless.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>), [visitor-counter](<https://devfeed.tech/tags/visitor-counter.md>)

### AI overview

A tutorial on building an animated visitor counter in a classic 1990s website style. It explains how to animate each digit independently, manage the counter and counting direction in a view model, keep composable UI components stateless and reusable, and connect the screen through navigation and Hilt.

### Source excerpt

Another step forward in recreating the icon 90s website look is the hit counter, visitor counter or web counter in classic squemorphic odometer style. I was inspired by a recent episode of Code with Italians where they animated a time field. I wanted to change the counter component to animate each number individually to get that odometer look. Before doing this though there was a question of state. I wanted to make a counter that would auto increment in a coroutine. It had to change direction up or down if you tapped it. To do this I decided to store the state and the counting direction in a view model. This allowed me to keep the components as stateless as possible. The components are re-usable because the logic that makes the numbers go up or down is held outside of the composable functions. The recommendation from Google is when you use a view model to hold state, keep it close to the root screen. I made a screen for my visitor counter and added it to my navigation code. Since I already had Hilt enabled in the project it was pretty easy to get hold of the viewmodel. The code snippet in the Navigation looks like this: NavHost(navController, startDestination = "overview") { //... other routes go here composable(route = "counter") { val viewModel: CounterViewModel = hiltViewModel() //<--- get the viewmodel from Hilt val count by viewModel.counter.collectAsState() //<--- the viewmodel exposes the counter as a StateFlow CounterScreen( count = count, onClick = { viewModel.onClick() } // <--- the viewmodel provides a method for when the element is clicked ) } } The CounterScreen is stateless and gets the value of the counter and the event handler as parameters. The CounterScreen has a Counter composable. The role of the Counter composable is to create a row of individual odometer numbers from the passed values. Also it should intercept a click and call the click handler. @Composable fun Counter( onClick: () -> Unit, count: Int, width: Int ) { val displayWidth = maxOf(3,

## Converting LiveData to Flow: More lessons learned

DevFeed: [Converting LiveData to Flow: More lessons learned](<https://devfeed.tech/articles/converting-livedata-to-flow-more-lessons-learned-25903.md>)

Original publisher: [Read original article](<https://chao2zhang.medium.com/converting-livedata-to-flow-more-lessons-learned-ba1e068115f5?source=rss-d19045640fe------2>)

Author: Chao Zhang

Published: 2021-06-23T06:52:18Z

Content type: tutorial

Language: en

Sources: [Stories by Chao Zhang on Medium](<https://devfeed.tech/sources/stories-by-chao-zhang-on-medium.md>)

Topics: [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [test](<https://devfeed.tech/topics/test.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [cancellation](<https://devfeed.tech/tags/cancellation.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [sharedflow](<https://devfeed.tech/tags/sharedflow.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>)

### AI overview

This continuation explains lessons from converting between Kotlin Flow and LiveData in Android. It covers unfinished hot-flow coroutines during unit tests, why asLiveData cancellation occurs after a timeout on Dispatchers.Main, and how values are replayed when LiveData becomes active again.

### Source excerpt

Photo: Buzz Andersen from Unsplash Android KTX provides opinionated methods facilitating using Kotlin Coroutines in Android Architecture Components. For instance, Flow<T>.asLiveData() is quite helpful to migrate your apps using LiveData towards coroutine. Make sure to understand their behaviors underneath before using them! This story is a continuation of the previous one. Lesson III: Unfinished coroutines during unit testshttps://medium.com/media/41979239402051494c1002bb4d9e57dc/href When converting from Flow to LiveData, the source stream might be a hot StateFlow like above. Running the test will actually end up with the following error: kotlinx.coroutines.test.UncompletedCoroutinesError: Unfinished coroutines during teardown. Ensure all coroutines are completed or cancelled by your test. We know a hot Flow like SharedFlow never completes, so this error appears reasonable. A common way to test hot flow is to cancel the coroutine that the hot flow is executed on. In this case, we may want to pass a custom coroutineContext to asLiveData(context = ...)and cancel the job when the assertions are done: https://medium.com/media/129968c37bf50ac019a25755e3c56411/href However, it does not work! Let's take a step back and consult the documentation of Flow<T>.asLiveData : If the LiveData becomes inactive (LiveData.onInactive) while the flow has not completed, the flow collection will be cancelled after timeoutInMs milliseconds unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation). Since we are converting a hot flow to LiveData, we will always meet the condition. The flow collection will be canceled after timeoutInMs (default is 5 seconds). After digging it a bit more into the source code, we find that the cancellation is implemented as a delay() call on Dispatchers.Main : https://medium.com/media/154954407331c372f002028c8353a843/href The reason why cancel()runs on Dispatchers.Main is because it is invoked byLiveData.onI

## Swipe to reveal in Jetpack Compose

DevFeed: [Swipe to reveal in Jetpack Compose](<https://devfeed.tech/articles/swipe-to-reveal-in-jetpack-compose-25899.md>)

Original publisher: [Read original article](<https://proandroiddev.com/swipe-to-reveal-in-jetpack-compose-6ffa8928a4c2?source=rss-56174fa84bcc------2>)

Author: Denys Rudenko

Published: 2021-02-19T17:21:58Z

Content type: tutorial

Language: en

Sources: [Stories by Denis Rudenko on Medium](<https://devfeed.tech/sources/stories-by-denis-rudenko-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [draggable](<https://devfeed.tech/topics/draggable.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-animation](<https://devfeed.tech/tags/compose-animation.md>), [draggable](<https://devfeed.tech/tags/draggable.md>), [gestures](<https://devfeed.tech/tags/gestures.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [swipe-to-reveal](<https://devfeed.tech/tags/swipe-to-reveal.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial showing how to implement swipe-to-reveal cards in Jetpack Compose by detecting horizontal drag gestures and managing revealed card state with a view model and StateFlow.

### Source excerpt

Swipe to dismiss is really easy to implement in compose, including item removal animation by using a combination of SwipeToDismiss & AnimatedVisibility composables. SwipeToDismiss doesn't allow us to stop the dragging motion midway though, so let's take a look how we can achieve the following by detecting horizontal drag gestures on any composable. https://medium.com/media/1a355b2d3e397414c51442342f16cda5/hrefStep 1: Creating a data source Those who've read expandable lists in jetpack compose can skip this step, since data source is almost the same. First we define our model to hold the card related info: data class CardModel(val id: Int, val title: String) We'll be using AAC viewModel example here, but feel free to use any "controller" abstraction you prefer. https://medium.com/media/28ca457093268969ac4f2e179ee860ef/href This class serves 5 purposes: Holds list of cards using MutableStateFlow in _cards field, and exposes a StateFlow to observers via cards field. Holds list of "revealed" card ids in _revealedCardIdsList, and exposes them to observers via revealedCardIdsList field. Provides list of cards using getFakeData() function. We need a coroutine here, to emit the testList into _cards. Has onItemExpanded() to mark cards as revealed, by adding tapped card id to _revealedCardIdsList, and notify observers about this change by mutating the state of _revealedCardIdsList. Has onItemCollapsed() to remove revealed card id from _revealedCardIdsList, and notify observers about this change by mutating the state of _revealedCardIdsList. Step 2: CardsScreen composablehttps://medium.com/media/4505fde17b0e8f9672f392cb9b3296f3/href We are observing the viewModel.cards containing our list of cards, and viewModel.expandedCardIds with the help of .collectAsStateWithLifecycle(). UI is quite simple here, each list item is represented with a Box that contains our hidden action icons & the draggable card. ActionsRow -- row with 3 icons, exposes callbacks from each icon tap: onDelete,

## Modelling UI State on Android

DevFeed: [Modelling UI State on Android](<https://devfeed.tech/articles/modelling-ui-state-on-android-25873.md>)

Original publisher: [Read original article](<http://lordraydenmk.github.io//2021/modelling-ui-state/>)

Author: Stojan Anastasov

Published: 2021-01-29T00:00:00Z

Content type: tutorial

Language: en

Sources: [Stojan Anastasov's blog](<https://devfeed.tech/sources/stojan-anastasov-s-blog.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [cardinality](<https://devfeed.tech/tags/cardinality.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [data-structure](<https://devfeed.tech/tags/data-structure.md>), [fp](<https://devfeed.tech/tags/fp.md>), [functional](<https://devfeed.tech/tags/functional.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [sealed-class](<https://devfeed.tech/tags/sealed-class.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [types](<https://devfeed.tech/tags/types.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This article explains how to model Android UI state in Kotlin using data classes and sealed classes. It connects types with sets and cardinality, then describes product types and sum types as tools for representing valid application states.

### Source excerpt

The recommended approach from Google for Android development is holding the UI state in a ViewModel and having the View observe it. To achieve that one can use LiveData, StateFlow, RxJava or a similar tool. But how to model the UI state? Use a data class or a sealed class? Use one observable property or many? I will describe the tradeoffs between the approaches and present a tool to help you decide which one to use. This article is heavily inspired by Types as Sets from the Elm guide, a large part is a translation from Elm to Kotlin. Photo by Marc-Olivier Jodoin on Unsplash Types as sets By Making Data Structure we can make sure the possible values in code exactly match the valid values in real life. Doing that helps to avoid a whole class of bugs related to invalid data. To achieve that, first we need to understand the relationship between Types and Sets. We can think of Types as sets of values, they contain unique elements and there is no ordering between them. For example: Nothing - the empty set, it contains no elements Unit - the singleton set, it contains one element - Unit Boolean - contains the elements true and false Int - contains the elements: ... -2, -1, 0, 1, 2 ... Float - contains the elements: 0.1, 0.01, 1.0 .... String - contains the elements: "", "a", "b", "Kotlin", "Android", "Hello world!"... So when you write: val x: Boolean it means x belongs to the set of Boolean values and can be either true or false. Cardinality In Mathematics, Cardinality is the measure of "number of elements" of a Set. For example the set of Boolean contains the elements [true, false] so it has a cardinality = 2. Let's take a look at the cardinality of the sets mentioned above: Nothing - 0 Unit - 1 Boolean - 2 Short - 65535 Int - ∞ Float - ∞ String- ∞ Note: The cardinality of Int and Float is not exactly infinity, it's 2^32 however that is a huge number. When building apps, we use built-in types and create custom types using constructs like data classes and sealed classes. Product

## Avoid backing properties for LiveData and StateFlow

DevFeed: [Avoid backing properties for LiveData and StateFlow](<https://devfeed.tech/articles/avoid-backing-properties-for-livedata-and-stateflow-25886.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/avoid-backing-properties-for-livedata-and-stateflow-706006c9867e?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-01-12T14:03:52Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [abstract-class](<https://devfeed.tech/tags/abstract-class.md>), [android](<https://devfeed.tech/tags/android.md>), [class](<https://devfeed.tech/tags/class.md>), [clean-code](<https://devfeed.tech/tags/clean-code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interface](<https://devfeed.tech/tags/interface.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [val](<https://devfeed.tech/tags/val.md>), [var](<https://devfeed.tech/tags/var.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This Kotlin article argues that developers can avoid duplicated backing properties when exposing LiveData and StateFlow. It proposes separating the public API from the implementation with interfaces or an abstract class, including in ViewModels.

### Source excerpt

https://unsplash.com/photos/OopPIi_A428 If you have ever worked with LiveData you probably have written code similar to this: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = _loading private val _loading = MutableLiveData<Boolean>()} This seems nowadays the typical way developers would expose some immutable LiveData, while being able to have a mutable version inside the implementation we would write data into. Every time I saw, or even had to write, this kind of code something cringed inside me. As I quoted in one of my talks this feeling in our brain is for real: social missteps activate regions in the brain, [..] that have been previously associated with physical pain. As developers, we know something is wrong with this code, right? It also feels like we are writing manual getters and setters here. What's wrong? We could start with the prefix we use for the backing field, although we fought hard for a long time to get rid of prefixes, we accept it here! It is even made it into the official coding conventions. But even if we rename it, it still cringes: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = mutableLoading private val mutableLoading = MutableLiveData<Boolean>()} This duplication feels unneeded! Especially if you write something like a ViewModel that exposed many of these, you get lost in reading the code just by all these duplications. But it's just LiveData? You might think it's just a specialty of LiveData and the future of that construct might be a more limited one. And you would not have this issue with primitives. The language supports this out of the box with a private setter: var secret: String = "Secret" private set But there is a new kid in town: StateFlow needs the same thing! Look at this snippet from the official Jetbrains blog: class DownloadingModel { private val _state = MutableStateFlow<DownloadStatus>(DownloadStatus.NOT_REQUESTED) val state: StateFlow<DownloadStatus> get() = _state This probl

## Expandable lists in Jetpack Compose

DevFeed: [Expandable lists in Jetpack Compose](<https://devfeed.tech/articles/expandable-lists-in-jetpack-compose-25896.md>)

Original publisher: [Read original article](<https://proandroiddev.com/expandable-lists-in-jetpack-compose-b0b78c767b4?source=rss-56174fa84bcc------2>)

Author: Denys Rudenko

Published: 2021-01-11T18:21:04Z

Content type: tutorial

Language: en

Sources: [Stories by Denis Rudenko on Medium](<https://devfeed.tech/sources/stories-by-denis-rudenko-on-medium.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [compose](<https://devfeed.tech/tags/compose.md>), [constraintlayout](<https://devfeed.tech/tags/constraintlayout.md>), [coroutine](<https://devfeed.tech/tags/coroutine.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [expandable-animation](<https://devfeed.tech/tags/expandable-animation.md>), [expandable-list](<https://devfeed.tech/tags/expandable-list.md>), [expandable-view](<https://devfeed.tech/tags/expandable-view.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [layout](<https://devfeed.tech/tags/layout.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [memory](<https://devfeed.tech/tags/memory.md>), [state](<https://devfeed.tech/tags/state.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

A tutorial explains how to build expandable lists in Jetpack Compose. It uses a card data class, a view model with StateFlow for cards and expanded card IDs, composable functions that observe state, and transition state to animate card expansion.

### Source excerpt

Expandable views are a common way to hide details of a visualised data structures. Let's take a look at how the following can be achieved in 6 steps, using compose: https://medium.com/media/b9dface7145a04eb3bee8ac03eed3a4e/hrefStep 1: Creating a data class for carddata class ExpandableCardModel(val id: Int, val title: String)Step 2: Create a data source We'll be using AAC viewModel example here, but feel free to use any "controller" abstraction you like. https://medium.com/media/61d179f82414c569e4d8e415bbed8aa6/href This class serves 4 purposes: Holds list of cards using MutableStateFlow in _cards field, and exposes a StateFlow to observers via cards field. Holds list of expanded card ids in _expandedCardIdsList, and exposes them to observers via expandedCardIdsList field. Provides list of cards using getFakeData() function. We need a coroutine here, to emit the testList into _cards. Contains a onCardArrowClicked() to mark cards as expanded by adding tapped card id to _expandedCardIdsList, and notify observers about this change by mutating the state of _expandedCardIdsList. Step 3: MainActivityhttps://medium.com/media/6e10348f08fc4004c3a397cd46c19bd0/href We are initialising the CardsViewModel here, and providing it to the CardsScreen composable function. Step 4: CardsScreen composablehttps://medium.com/media/b2cd50c3ab379cd75897eda6b1aca4c6/href We are observing the viewModel.cards containing our list of cards, and viewModel.expandedCardIds with the help of .collectAsState(). What's the purpose of .collectAsState()? It's converting StateFlow into a State. Update: using .collectAsStateWithLifecycle() which is the same thing, but lifecycle aware, and helps to reduce memory consumption when UI is not visible to the user. More info in this article. What's a State? From the documentation: " State is a value holder where reads to the value property during the execution of a composable function, the current recomposeScope will be subscribed to changes of that value." Step

## Using Kotlin StateFlow for state management in Android

DevFeed: [Using Kotlin StateFlow for state management in Android](<https://devfeed.tech/articles/stateflow-end-of-livedata-25752.md>)

Original publisher: [Read original article](<https://blog.shreyaspatil.dev/stateflow-end-of-livedata-a473094229b3/>)

Author: Shreyas Patil

Published: 2020-05-22T15:49:15Z

Content type: tutorial

Language: en

Sources: [Shreyas Patil's Blog](<https://devfeed.tech/sources/shreyas-patil-s-blog.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android](<https://devfeed.tech/topics/android.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Code](<https://devfeed.tech/topics/code.md>), [App](<https://devfeed.tech/topics/app.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app](<https://devfeed.tech/tags/app.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [flow](<https://devfeed.tech/tags/flow.md>), [getting-started](<https://devfeed.tech/tags/getting-started.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [others](<https://devfeed.tech/tags/others.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [ui](<https://devfeed.tech/tags/ui.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how to use Kotlin Coroutines StateFlow for state management in Android, demonstrates it in a counter app, and compares its implementation with LiveData. It notes that StateFlow supports flow operators such as combine and zip, while some LiveData callback-style features were not yet supported at the time described.

### Source excerpt

Is StateFlow the end of LiveData? An opinionated look at how Kotlin's StateFlow is replacing LiveData for state management in Android.