# Stories by Nav Singh 🇨🇦 on Medium

Stories by Nav Singh on Medium

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

## From Permissions to Sessions: Rethinking Location Access in Android 17

DevFeed: [From Permissions to Sessions: Rethinking Location Access in Android 17](<https://devfeed.tech/articles/from-permissions-to-sessions-rethinking-location-access-in-android-17-25982.md>)

Original publisher: [Read original article](<https://proandroiddev.com/from-permissions-to-sessions-rethinking-location-access-in-android-17-5a13124b777d?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-09-03T18:18:32Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Mobile](<https://devfeed.tech/topics/mobile.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>), [android-permissions](<https://devfeed.tech/tags/android-permissions.md>), [android17](<https://devfeed.tech/tags/android17.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [branding](<https://devfeed.tech/tags/branding.md>), [consent](<https://devfeed.tech/tags/consent.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [layout](<https://devfeed.tech/tags/layout.md>), [permissions](<https://devfeed.tech/tags/permissions.md>)

### AI overview

A tutorial on implementing Android 17's system-rendered Location Button in Jetpack Compose applications. It explains session-only precise location access, the USE_LOCATION_BUTTON permission, the required Jetpack library, fallback rendering, and UI customization.

### Source excerpt

Image generated using Gemini In this article, we will learn how to implement the new 📍Location button introduced in Android 17 in Jetpack Compose-based Android applications. Android 17 adds a system-rendered 📍Location Button that we can drop into the layout via a Jetpack library, and tapping it gives the app precise location for that session only, gated by a new USE_LOCATION_BUTTON permission. What the feature is Android now exposes a system-owned, standard location button that we can embed in our UI instead of designing a custom control. When the user taps it, the system handles the permission flow, then grants the app precise location for the current session only, rather than long-lived access. How it changes permissions Instead of immediately requesting ACCESS_FINE_LOCATION (and maybe ACCESS_COARSE_LOCATION) at runtime, we declare the new USE_LOCATION_BUTTON permission to host the button. <!-- Standard Coarse and Fine Location Permissions + onlyForLocationButton --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:usesPermissionFlags="onlyForLocationButton"/> <!-- Required system permission for rendering the LocationButton --> <uses-permission android:name="android.permission.USE_LOCATION_BUTTON" />Developer benefits Less custom permission boilerplate: We lean on system UX and the Jetpack library for the hardest parts of location consent. [versions] locationbuttonCompose = "1.0.0-alpha01" [libraries] androidx-locationbutton-compose = { group = "androidx.core.locationbutton", name = "locationbutton-compose", version.ref = "locationbuttonCompose" } Higher trust and clarity for users: the control looks and behaves consistently across apps, and session-only precise access is easier to understand than broader access. Implementation As we all know, Android development is now Compose-first, so we will implement it using the LocationButton composable provided by th

## Mastering Jetpack Compose's New SelectionState API

DevFeed: [Mastering Jetpack Compose's New SelectionState API](<https://devfeed.tech/articles/mastering-jetpack-compose-s-new-selectionstate-api-25985.md>)

Original publisher: [Read original article](<https://proandroiddev.com/mastering-jetpack-composes-new-selectionstate-api-13dfa05f49db?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-08-27T01:17:44Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [api](<https://devfeed.tech/tags/api.md>), [api-news](<https://devfeed.tech/tags/api-news.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [reactive](<https://devfeed.tech/tags/reactive.md>)

### AI overview

This tutorial introduces Jetpack Compose's SelectionState API, released in August 2026, for hoisted bidirectional selection control and reactive text observation. It demonstrates programmatic selection, clearing, range selection, word-based expansion, and access to selected text.

### Source excerpt

Image generated using Gemini The Jetpack Compose August '26 release introduced a new API SelectionState for hoisted, bidirectional control and reactive text observation. Core ComponentsSelectionState An object that provides access to the selected text and methods for controlling it programmatically 🛑 We cannot use the same SelectionState with multiple SelectionContainersval selectionState = rememberSelectionState()SelectionContainer: A composable function that enables text selection of its content. SelectionContainer(state = selectionState) { Text( "Text content to be selected programmatically." ) }Programmatic Control Methods selectionState.selectAll(): Selects all the content in the container Button( onClick = { selectionState.selectAll() }) { Text("Select All") } selectionState.clear(): Clears the active selection Button(onClick = { selectionState.clear() }) { Text("Clear selection") } selectionState.select(TextRange): Selects a specific range of text Button( onClick = { selectionState.select(TextRange(0, 4)) }) { Text("Range selection") } selectionState.extendSelectionByWord(): Expands the selection of words This selects the first word in the container if there is no selection. The selection continues to the next Composable Text, if the next word is in a different Composable Text.Button( onClick = { selectionState.extendSelectionByWord()}) { Text("Extend selection") }Mutliple Text Components selectionSelected texts Provides access to the selected text. Returns List<AnnotatedString> Backed by mutableStateOf -- Observable by Composablesprivate var _selectedTexts by mutableStateOf<List<AnnotatedString>>Text(text = "Selected text: ${selectionState.selectedTexts}")Sample Code@Composable fun ProgrammaticSelectionExample() { val selectionState = rememberSelectionState() Column{ Row { Button( onClick = { selectionState.selectAll() }, ) { Text("Select All") } Button( onClick = { selectionState.clear() }, ) { Text("Clear selection") } } Row { Button( onClick = { selectionS

## Implement Android 17's Contact Picker

DevFeed: [Implement Android 17's Contact Picker](<https://devfeed.tech/articles/ditch-read-contacts-forever-android-17-s-secure-contact-picker-25981.md>)

Original publisher: [Read original article](<https://proandroiddev.com/ditch-read-contacts-forever-android-17s-secure-contact-picker-24c5c69b3b51?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-06-07T19:28:49Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android17](<https://devfeed.tech/tags/android17.md>), [androidappdevelopment-usa](<https://devfeed.tech/tags/androidappdevelopment-usa.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [contactpicker](<https://devfeed.tech/tags/contactpicker.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [permission](<https://devfeed.tech/tags/permission.md>), [privacy](<https://devfeed.tech/tags/privacy.md>)

### AI overview

A tutorial on implementing Android 17's Contact Picker as a privacy-preserving alternative to READ_CONTACTS. It covers requesting contact data fields, launching the picker, handling result URIs, multi-selection, and compatibility behavior.

### Source excerpt

Image generated using Perplexity In this article, we will learn how to implement the new Contact Picker introduced in Android17. Contact picker | Android Developers Contact picker -- Android17 It is a standardized, browsable interface for sharing contacts. A privacy-preserving alternative to the READ_CONTACTS permission, the picker runs on Android 17 and higher. 🪦 READ_CONTACTS Permission 🪦 It grants apps full, persistent access to all contact data -- names, phone numbers, emails, etc -- after a one-time user approval (runtime permission). Protection level: dangerous ⛔ Apps specify which data fields they need, such as phone numbers or email addresses, and users select specific contacts to share. With built-in search, profile switching, and multi-selection capabilities, the app reads only the selected data, ensuring granular control. Implementation Intent Action: ACTION_PICK_CONTACTS We will be able to specify multiple data fields our app will need at once. We do this using Intent.EXTRA_REQUESTED_DATA_FIELDS, passing an ArrayList<String> of MIME types defined in ContactsContract.CommonDataKinds. MIME Types: //... ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE //...Define the ActivityResultLauncherval contactPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == Activity.RESULT_OK) { val uri = result.data?.data ?: return@rememberLauncherForActivityResult // Process the result URI.... processCPResultUri(uri, context) } }Launch the ContactPicker 📲 Define the intent val requestedFields = arrayListOf( ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE ) // Set up the intent val pickContactIntent = Intent(ContactsPickerSessionContract.ACTION_PICK_CONTACTS).apply { // Enable multi-select - true/false putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) // Set limit of selectable contacts putExtra(EXTRA_PICK_CONTACTS_SE

## Kotlin 2.4 Brings Swift-Style Collection Syntax \[\]

DevFeed: [Kotlin 2.4 Brings Swift-Style Collection Syntax \[\]](<https://devfeed.tech/articles/kotlin-2-4-brings-swift-style-collection-syntax-25983.md>)

Original publisher: [Read original article](<https://proandroiddev.com/kotlin-2-4-brings-swift-style-collection-syntax-0ab7097aa166?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-06-04T16:32:23Z

Content type: article

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

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

Tags: [build](<https://devfeed.tech/tags/build.md>), [collection](<https://devfeed.tech/tags/collection.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [experimental](<https://devfeed.tech/tags/experimental.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-2](<https://devfeed.tech/tags/kotlin-2.md>), [kotlin-standard-library](<https://devfeed.tech/tags/kotlin-standard-library.md>), [new-features](<https://devfeed.tech/tags/new-features.md>), [syntax](<https://devfeed.tech/tags/syntax.md>)

### AI overview

This article explains Kotlin 2.4's experimental collection literals, which allow collections to be initialized with bracket syntax instead of functions such as listOf() or mutableListOf(). It also covers enabling the feature with the compiler option and discusses explicit declarations and type inference.

### Source excerpt

Image generated using Perplexity In Kotlin 2.4, collection literals are introduced, making collection initialization more concise and readable. To define collections, we no longer need to use functions like listOf() or mutableListOf(). This reduces boilerplate and makes intent clearer at a glance, especially when working with simple, static data. It's currently an experimental feature. We need to opt in, and the syntax or behavior may evolve in future releases. Add the Xcollection-literals compiler option to the build file kotlin { jvmToolchain(21) compilerOptions { freeCompilerArgs.add("-Xcollection-literals") } }Code samples Bracket syntax [] + explicit declaration // Mutable list with explicit type declaration // val plFNames: MutableList<String> = mutableListOf("Joe", "Alice") // Mutable list with brackets syntax val plFNames: MutableList<String> = ["Joe", "Alice"] println(plFNames) // ["Joe", "Alice" ] Bracket syntax [] + type inference As per docs:Compiler defaults to List if it lacks sufficient information to infer the collection type.But it seems like Array as we can see in the screenshot 📸 👇 val plFNames = ["Joe", "Alice"] println(plFNames) // ["Joe", "Alice" ]Screenshot type inference -- typeReferences What's new in Kotlin 2.4.0 | Kotlin Kotlin 2.4 Brings Swift-Style Collection Syntax [] was originally published in ProAndroidDev on Medium, where people are continuing the conversation by highlighting and responding to this story.

## Migrating to AGP 9.2.1: Kotlin build errors I hit and how I fixed them

DevFeed: [Migrating to AGP 9.2.1: Kotlin build errors I hit and how I fixed them](<https://devfeed.tech/articles/migrating-to-agp-9-2-1-kotlin-build-errors-i-hit-and-how-i-fixed-them-25977.md>)

Original publisher: [Read original article](<https://navczydev.medium.com/migrating-to-agp-9-2-1-kotlin-build-errors-i-hit-and-how-i-fixed-them-1565bb36b96f?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-05-27T01:03:56Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [migration](<https://devfeed.tech/topics/migration.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [developer tooling](<https://devfeed.tech/topics/developer-tooling.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [dagger-hilt](<https://devfeed.tech/tags/dagger-hilt.md>), [errors](<https://devfeed.tech/tags/errors.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [ksp](<https://devfeed.tech/tags/ksp.md>), [migration](<https://devfeed.tech/tags/migration.md>)

### AI overview

A tutorial documenting a small Android project migration to AGP 9.2.1. It explains build errors caused by AGP 9's built-in Kotlin support and shows fixes involving removal of the old Kotlin Android plugin, migration from KAPT to KSP for Hilt, and replacement of the legacy kotlinOptions DSL.

### Source excerpt

Image generate using perplexity I recently upgraded an Android project to AGP 9.2.1 and ran into a chain of build errors. In my case, the project was a very small app, so there might be more issues if the project setup is complicated. Each one pointed to a different part of the new Kotlin/Gradle setup, and fixing them one by one made the migration much clearer. Why this happened AGP 9 introduces built-in Kotlin support that changes the old plugin setup (org.jetbrains.kotlin.android). 🛑 kapt, and kotlinOptions no longer work the same way. Error 1: Cannot add extension with name kotlinCannot add extension with name 'kotlin', as there is an extension already registered with that name. The fix was to remove the Kotlin Android plugin from the module and any root-level declarations that still applied it. AGP 9 already provides Kotlin support, so applying the old plugin causes a duplicate kotlin extension.Fixplugins { id("com.android.application") // remove: id("org.jetbrains.kotlin.android") }Error 2: org.jetbrains.kotlin.kapt is not compatible with built-in Kotlin support After removing the Kotlin Android plugin, the next failure came from kapt The 'org.jetbrains.kotlin.kapt' plugin is not compatible with built-in Kotlin support. Android's migration guide recommends moving to KSP, or using com.android.legacy-kapt only as a temporary fallback.Fix After removing kapt, we need to update the affected libraries. In my case, only Hilt was affected, so I updated it with the KSP plugins { //.... // Remove KAPT kotlin("kapt") // Add KSP id("com.google.devtools.ksp") } // dependencies dependencies { // kapt(libs.hilt.compiler) ksp(libs.dagger.hilt.compiler) // ... }Error 3: Unresolved reference: kotlinOptions Once kapt was out of the way, the build hit another issue 🤯 Unresolved reference 'kotlinOptions' That's because AGP 9 built-in Kotlin uses the new Kotlin compiler options DSL instead of the old android.kotlinOptions {} block. The Android migration doc says to move those setti

## Simplify Sorted-Order Validation with Kotlin 2.4.0's New Extensions

DevFeed: [Simplify Sorted-Order Validation with Kotlin 2.4.0's New Extensions](<https://devfeed.tech/articles/simplify-sorted-order-validation-with-kotlin-2-4-0-s-new-extensions-25978.md>)

Original publisher: [Read original article](<https://navczydev.medium.com/simplify-sorted-order-validation-with-kotlin-2-4-0s-new-extensions-b48b1ac10521?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-04-06T02:23:40Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

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

Tags: [code](<https://devfeed.tech/tags/code.md>), [extension](<https://devfeed.tech/tags/extension.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-2](<https://devfeed.tech/tags/kotlin-2.md>), [kotlin-beginners](<https://devfeed.tech/tags/kotlin-beginners.md>), [kotlin-standard-library](<https://devfeed.tech/tags/kotlin-standard-library.md>), [library](<https://devfeed.tech/tags/library.md>), [sortedlist](<https://devfeed.tech/tags/sortedlist.md>), [sorting](<https://devfeed.tech/tags/sorting.md>), [standard-library](<https://devfeed.tech/tags/standard-library.md>)

### AI overview

This article introduces Kotlin 2.4.0-Beta1 standard-library extension functions for checking whether collections are sorted. It covers ascending, descending, comparator-based, and selector-based checks, which return true for correctly ordered collections or collections with fewer than two elements. The checks stop when they find an unordered pair.

### Source excerpt

Image generated using Perplexity Kotlin 2.4.0-Beta1 introduces a small but powerful addition to the standard library: a set of new extension functions that lets us check whether a collection is already sorted. With these extension functions, we can check whether elements have already been sorted without resorting them. New Functions .isSorted() .isSortedDescending() .isSortedWith(comparator) .isSortedBy(selector) .isSortedByDescending(selector) All of these return true if: The elements are in the expected order, or The collection has fewer than two elements.These functions are optimized -- they stop checking as soon as an unordered pair is found, so they handle large inputs efficiently.Code samplesdata class User(val name: String, val age: Int)fun main() { val numbers = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) println("Numbers: isSorted") println(numbers.isSorted()) // true println("Is sorted descending") println(numbers.isSortedDescending()) // false // Users list val users = listOf( User("Alice", 21), User("Balley", 34), User("Charles", 29), ) println("Users: isSorted by Age") println(users.isSortedBy(User::age)) // false val comparator = Comparator<User>{ user, user2 -> user.name.length.compareTo(user2.name.length) } println("Users: isSortedWith(comparator)") val sortedList = users.sortedWith(comparator) println("Users: Name by length ${sortedList.joinToString()}") // Output: Users: Name by length User(name=Bob, age=31), User(name=Alice, age=24), User(name=Charlie, age=29) println(sortedList.isSortedWith(comparator)) // true }References What's new in Kotlin 2.4.0-Beta1 | Kotlin

## Integrating the biometric-compose Library with Android Compose Applications

DevFeed: [Integrating the biometric-compose Library with Android Compose Applications](<https://devfeed.tech/articles/biometric-auth-in-compose-made-easy-the-new-library-you-need-25980.md>)

Original publisher: [Read original article](<https://proandroiddev.com/biometric-auth-in-compose-made-easy-the-new-library-you-need-29814270506d?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-04-02T02:28:19Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [Authentication](<https://devfeed.tech/topics/authentication.md>), [Android](<https://devfeed.tech/topics/android.md>), [Library](<https://devfeed.tech/topics/library.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Code](<https://devfeed.tech/topics/code.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>), [article](<https://devfeed.tech/tags/article.md>), [auth](<https://devfeed.tech/tags/auth.md>), [authentication](<https://devfeed.tech/tags/authentication.md>), [biometric-authentication](<https://devfeed.tech/tags/biometric-authentication.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [library](<https://devfeed.tech/tags/library.md>)

### AI overview

This tutorial explains how to integrate the biometric-compose library into Android applications built with Jetpack Compose. It covers rememberAuthenticationLauncher, authentication callbacks, result handling, prompt configuration and customization, and authentication fallbacks.

### Source excerpt

Image generated using Perplexity In this article, we will learn how to integrate a new library biometric-compose into Android applications for Biometric integration. A new biometric-compose library simplifies the integration of biometrics into Compose-based applications. ImplementationDependencies implementation("androidx.biometric:biometric:1.4.0-alpha06") implementation("androidx.biometric:biometric-compose:1.4.0-alpha06")rememberAuthenticationLauncherrememberAuthenticationLauncher A composable function to streamline biometric authentication requests and callbacks directly in composables. It returns AuthenticationResultLauncher that we can use to initiate the authentication process. We need to pass a callback of type AuthenticationResultCallback . It will be called when an AuthenticationResult is available. A successful or error result will be delivered to AuthenticationResultCallback.onAuthResult , and failures will be delivered to AuthenticationResultCallback.onAuthAttemptFailed, which is set by a callback. The 👆callback will be executed on the main thread.fun AuthenticationResult.processAuthResult(){ when (this) { is AuthenticationResult.Success -> Log.d(TAG, "AuthenticationResult Success, \nAuth type: $authType, \nCrypto object: $crypto") is AuthenticationResult.Error -> Log.d(TAG,"AuthenticationResult Error, \nError code: $errorCode, \nErr string: $errString") is AuthenticationResult.CustomFallbackSelected -> { Log.d(TAG,"AuthenticationResult CustomFallbackSelected ${fallback.text}") } } }AuthenticationResultTypeAuthenticationResultTypeDemo AuthenticationResultTypeAuthenticationError (Error code)AuthenticationError (Error code)Demo AuthenticationError (Error code)🧑💻 Code: rememberAuthenticationLauncherval launcher = rememberAuthenticationLauncher( resultCallback = object : AuthenticationResultCallback { override fun onAuthResult(result: AuthenticationResult) { Log.d(TAG, "onAuthResult: $result") processAuthResult() } override fun onAuthAttemptFailed() { supe

## Meet FlexBox: The Powerful New Layout System for Compose

DevFeed: [Meet FlexBox: The Powerful New Layout System for Compose](<https://devfeed.tech/articles/meet-flexbox-the-powerful-new-layout-system-for-compose-25986.md>)

Original publisher: [Read original article](<https://proandroiddev.com/meet-flexbox-the-powerful-new-layout-system-for-compose-446b1f65cc62?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-03-27T18:22:23Z

Content type: article

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

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

Tags: [3](<https://devfeed.tech/tags/3.md>), [adaptive](<https://devfeed.tech/tags/adaptive.md>), [alignment](<https://devfeed.tech/tags/alignment.md>), [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>), [api](<https://devfeed.tech/tags/api.md>), [code](<https://devfeed.tech/tags/code.md>), [compose](<https://devfeed.tech/tags/compose.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [container](<https://devfeed.tech/tags/container.md>), [css](<https://devfeed.tech/tags/css.md>), [flexbox](<https://devfeed.tech/tags/flexbox.md>), [introduction](<https://devfeed.tech/tags/introduction.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [layout](<https://devfeed.tech/tags/layout.md>), [space](<https://devfeed.tech/tags/space.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial introduces FlexBox, a new Jetpack Compose layout system inspired by CSS Flexbox. It explains how FlexBox arranges children dynamically and covers FlexBoxConfig parameters for direction, wrapping, alignment, spacing, and item distribution, along with Modifier.flex controls and code samples.

### Source excerpt

Header image Jetpack Compose continues to evolve, and with the introduction of the new FlexBox layout, we finally have a powerful, flexible way to design adaptive UIs -- inspired by the CSS Flexbox model. https://developer.android.com/develop/ui/compose/layouts/adaptive/flexbox If you've ever used Row, Column, or FlowRowYou'll feel right at home. FlexBox acts as a superset, combining their capabilities while providing granular control over alignment, wrapping, and item distribution. Until now, we had to choose between rigid layouts (Row/Column) or more dynamic ones (FlowRow/FlowColumn). FlexBox merges the best of both worlds -- flexibility and simplicity. What Is FlexBox? Composable brings the concept of flexible layouts from the web into Jetpack Compose. Arranges its children dynamically, allowing them to grow, shrink, or wrap based on available space and configuration. Preview FlexBoxFlexBox API🏗 Building blocks and their roles.FlexBoxThe main composable responsible for arranging children.FlexBox( config = { direction(FlexDirection.Row) wrap(FlexWrap.Wrap) justifyContent(FlexJustifyContent.SpaceBetween) alignItems(FlexAlignItems.Center) gap(8.dp) }, modifier = Modifier .border(1.dp, Color.Black) ) { Text( "Item 1", Modifier .flex { grow(1f) } .background(color = randomColor()) .border(1.dp, Color.Black) ) Text( "Item 2", Modifier .flex { basis(80.dp) } .background(color = randomColor())) }Screenshot FlexBox SampleFlexBoxConfigConfigures the container's layout behavior -- direction, wrapping, justification, alignment, and spacing. Key parameters: direction: Controls the main axis (Row, Column). wrap: Determines if items flow onto new lines. Here we have 3 options: Wrap, NoWrap, WrapReverse justifyContent: Distributes space along the main axis(start, end, etc). alignItems: Defines how items align on the cross-axis(start, end, etc). alignContent: Controls how multiple lines are distributed along the cross-axis. This applies only when the wrap is FlexWrap.Wrap or FlexWr

## Beyond Positions: Kotlin's New Name-Based Destructuring

DevFeed: [Beyond Positions: Kotlin's New Name-Based Destructuring](<https://devfeed.tech/articles/beyond-positions-kotlin-s-new-name-based-destructuring-25979.md>)

Original publisher: [Read original article](<https://proandroiddev.com/beyond-positions-kotlins-new-name-based-destructuring-eee347d1bb5c?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-03-18T01:24:50Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [properties](<https://devfeed.tech/topics/properties.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>), [compiler](<https://devfeed.tech/tags/compiler.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-2](<https://devfeed.tech/tags/kotlin-2.md>), [kotlin-native](<https://devfeed.tech/tags/kotlin-native.md>), [properties](<https://devfeed.tech/tags/properties.md>)

### AI overview

This tutorial explains Kotlin 2.3.20's experimental name-based destructuring declarations, which match variables to properties instead of relying on componentN() position. It also covers the compiler option and supported modes.

### Source excerpt

Image generated using Perplexity Name-based destructuring declarations were introduced in Kotlin 2.3.20 and match variables to properties rather than relying on position-based componentN(). Previously, destructive declarations used position-based destruction: data class User(var firstName: String, var lastName: String) val user = User("Alice", "Husseini") // componentN() val(firstName,lastName) = user println(firstName) println(lastName)Drawback of the componentN() based approach Destructuring relies on the order of componentN() functions, lastName receives the value of firstName, and firstName receives the value of lastName 👇 data class User(var firstName: String, var lastName: String) val user = User("Alice", "Husseini") // componentN() val(lastName,firstName) = user println(firstName) -> Husseini println(lastName) -> AliceName-based destructuring ✨ It's an Experimental feature. We can control how the compiler interprets destructuring declarations with the -Xname-based-destructuring compiler option. kotlin { // .. compilerOptions { freeCompilerArgs.add("-Xname-based-destructuring=only-syntax") } }Each variable refers to a property by name.val user = User("Alice", "Husseini") // Name-based destructuring (val firstName = firstName, val lastName = lastName) = userModeshttps://kotlinlang.org/docs/whatsnew2320.html#languageMode -- Name-Mismatch⚠ Warning ⚠Name-Mismatch warningMode -- Complete Position-based destructuring using square brackets []: data class User(var firstName: String, var lastName: String) val user = User("Alice", "Husseini") // componentN() val [firstName,lastName] = userReferences What's new in Kotlin 2.3.20 | Kotlin Stay in touch https://www.linkedin.com/in/navczydev/ JavaScript is not available. navczydev - Overview navczydev.bsky.social Beyond Positions: Kotlin's New Name-Based Destructuring was originally published in ProAndroidDev on Medium, where people are continuing the conversation by highlighting and responding to this story.

## Jetpack Compose Material 3 unifies theme data in LocalMaterialTheme

DevFeed: [Jetpack Compose Material 3 unifies theme data in LocalMaterialTheme](<https://devfeed.tech/articles/localmaterialtheme-from-prop-hell-to-theme-nirvana-material3-25984.md>)

Original publisher: [Read original article](<https://proandroiddev.com/localmaterialtheme-from-prop-hell-to-theme-nirvana-material3-38b3c01ab7d4?source=rss-711ab22c5c77------2>)

Author: Nav Singh

Published: 2026-03-12T19:38:30Z

Content type: tutorial

Language: en

Sources: [Stories by Nav Singh 🇨🇦 on Medium](<https://devfeed.tech/sources/stories-by-nav-singh-on-medium.md>)

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

Tags: [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [design-systems](<https://devfeed.tech/tags/design-systems.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [material-design](<https://devfeed.tech/tags/material-design.md>), [material3](<https://devfeed.tech/tags/material3.md>)

### AI overview

Jetpack Compose Material 3 1.5.0-alpha15 changes MaterialTheme to use one LocalMaterialTheme CompositionLocal for color, typography, shapes, and motion. The article explains how this can simplify theme management and allow custom modifier nodes to read theme data outside composable scopes.

### Source excerpt

Image generated using Perplexity Jetpack Compose Material 3 1.5.0-alpha15 introduces a subtle but powerful refactor MaterialTheme now uses a single LocalMaterialTheme CompositionLocal instead of separate locals for color, typography, shapes, and motion. While this simplifies internal theme management, its real value emerges when building custom design systems and theme-aware Modifier libraries. The Refactor: Cleaner Under the Hood Previously, MaterialTheme relied on multiple CompositionLocals: Source:https://android-review.googlesource.com/c/platform/frameworks/support/+/3949000/16/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt Now: Everything flows through one unified source: Source:https://android-review.googlesource.com/c/platform/frameworks/support/+/3949000/16/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.ktThis reduces allocations and simplifies the theme provider.⭐ Where It Shines: Design Systems & Custom Modifiers ⭐ The game-changer is CompositionLocalConsumerModifierNode support. Custom Modifiers that handle drawing/layout outside @Composable scopes can now read theme data directly:object BrandGradientOverlayElement : ModifierNodeElement<BrandGradientOverlayNode>() { override fun create(): BrandGradientOverlayNode = BrandGradientOverlayNode() override fun update(node: BrandGradientOverlayNode) { // No-Op } override fun InspectorInfo.inspectableProperties() { name = "brandGradientOverlay" } override fun equals(other: Any?): Boolean = (this === other) override fun hashCode(): Int = javaClass.hashCode() } class BrandGradientOverlayNode : Modifier.Node(), DrawModifierNode, CompositionLocalConsumerModifierNode { override fun ContentDrawScope.draw() { // Read color scheme to access colors val colorScheme = currentValueOf(MaterialTheme.LocalMaterialTheme).colorScheme val gradient = Brush.linearGradient( listOf( colorScheme.primary, colorScheme.secondary) ) drawContent() d