AndroidBriefActions - Android library for sending and observing non persistent actions such as showing a message; nice readable way to call navigation actions from ViewModel or Activity/Fragment.

Overview

Download License API

implementation "com.vladmarkovic.briefactions:briefactions:$briefActionsVersion"

Benefits

Why use brief-actions library pattern:

  • Prevent short-term actions reoccurring (i.e. on screen rotation)
  • Easy, readable and intuitive way to call display and navigation actions
  • Code traceability
  • Default observe function allows only one observer to subscribe.

On Android, in combination with LiveData, ViewModel is more than what it might be on some other platforms. It also represents an architectural component for easy state management across view lifecycle events. When an Activity or Fragment gets recreated, subscribing to observe LiveData gives us the latest value, thus orientation changes are easy to manage. But sometimes this is not desirable. Some state delivered by certain action might be only relevant at the time when the action happened. For instance, navigating to another screen, or displaying a non-persistent message. In these cases we would not want another screen to open again or another message to show again when we rotate the device (value is preserved in LiveData).

BriefAction type represents these actions and in combination with LiveAction, helper observers, ViewModel and the rest of the pattern, enables consuming of such actions only once.

The beauty of this pattern is in its easy use and the way it nicely and intuitively reads for initiating display or navigation actions from a ViewModel simply by calling:.

  • display(ShowMessage(R.string.hello)) or
  • navigateTo(SettingsScreen)

or from Activity / Fragment

  • viewModel.display(ShowMessage(R.string.hello)) or
  • viewModel.navigateTo(SettingsScreen)

Another benefit is improving code traceability, which is often a disadvantage of MVVM comparing to MVP.
Using command+tap on the defined action, we can trace where it is used or handled.

Also, by default observe function allows only one observer to subscribe for observing display or navigation actions. This ensures prevention of opening the same screen or showing of same message multiple times. If you want you can override this behaviour by passing true as the last function param.

Use

  • Extend the library ViewModel when you create your view model.
  • Create your BriefActions (inside VM for scoping or outside).
  • Call them with display or navigateTo functions defined in the ViewModel.
    You can call them directly from the view model, or from Activity / Fragment.
  • Observe them inside Activity / Fragment.
    Important Note:
    DisplayAction and NavigationAction are sent using LiveAction which by default allows for only one observer to subscribe with the default observe function. If you want to enable multiple observers, you will need to explicitly pass true for the last add param.
    So:
    • viewModel.displayActions.observe(lifecycleOwner: LifecycleOwner, observer: Observer<in A>) is equivalent to setObserver
    • viewModel.displayActions.observe(lifecycleOwner: LifecycleOwner, observer: Observer<in A>, add = true) is equivalent to addObserver
      (same for viewModel.navigationActions)
      Just be aware that:
    • if you add several observers and then set one after them, it will remove all the previously added ones.
    • if you set an observer and then add one after, there will be two subscribed.

Example

class MyViewModel(private val auth: SomeAuth) : ViewModel() {

    //...
    
    fun login(userId: String, password: String) {
        if (userId.isNotBlank() && password.isNotBlank()) {
            signIn(userId, password)
        } else {
            display(ShowMessage("Please fill out all the fields."))
        }
    }
    
    private fun signIn(userId: String, password: String) {
        // helper extension function for launching a coroutine
        launchHandleOnMain {
            suspended = {
                success = auth.signIn(userId, password)
                if (success) navigateTo(DashboardScreen(userId))
                else navigateTo(SignUpScreen)
            },
            onError = { error ->
                display(error.message) 
            }
        }
    }


    sealed class MyNavigationAction : NavigationAction {
        object SignUpScreen : MyNavigationAction()
        data class DashboardScreen(val userId: String) : MyNavigationAction()
    }
}
data class ShowMessage(val message: String) : DisplayAction()
class MyActivity : AppCompatActivity() {

    private val viewModel by viewModel<MyViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //...
        viewModel.display(ShowMessage("Hello!"))
        
        viewModel.observe(this, DisplayActionObserver { displayAction ->
            when (val data = displayAction) {
                is ShowMessage -> Toast.makeText(this, data.message, Toast.LENGTH_SHORT).show()
            }
        })
        
        viewModel.observe(this, NavigationActionObserver { navigationAction ->
            when (navigationAction) {
                is MyNavigationAction -> handleMyNavigationAction(navigationAction)
            }
        })
    }
    
    private fun handleMyNavigationAction(navigateTo: MyNavigationAction) =
        when (val data = navigateTo) {
            is SignUpScreen -> startActivity(SignUpActivity.newIntent())
            is DashboardScreen -> startActivity(DashboardActivity.newIntent(data.userId))
        }
}

License

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You might also like...
Bottom-App-Bar-with-Bottom-Navigation-in-Jetpack-compose-Android - Bottom App Bar with Bottom Navigation in Jetpack compose
Bottom-App-Bar-with-Bottom-Navigation-in-Jetpack-compose-Android - Bottom App Bar with Bottom Navigation in Jetpack compose

Bottom-App-Bar-with-Bottom-Navigation-in-Jetpack-compose-Android This is simple

New style for app design simple bottom navigation with side navigation drawer UI made in Jetpack Compose.😉😎
New style for app design simple bottom navigation with side navigation drawer UI made in Jetpack Compose.😉😎

BottomNavWithSideDrawer New style for app design simple bottom navigtaion with side navigation drawer UI made in Jetpack Compose. 😉 😎 (Navigation Co

Navigation Drawer Bottom Navigation View
Navigation Drawer Bottom Navigation View

LIVE #019 - Toolbar, Navigation Drawer e BottomNavigationView com Navigation Com

🎉 [Android Library] A light-weight library to easily make beautiful Navigation Bar with ton of 🎨 customization option.
🎉 [Android Library] A light-weight library to easily make beautiful Navigation Bar with ton of 🎨 customization option.

Bubble Navigation 🎉 A light-weight library to easily make beautiful Navigation Bars with a ton of 🎨 customization options. Demos FloatingTopBarActiv

A small and simple, yet fully fledged and customizable navigation library for Jetpack Compose
A small and simple, yet fully fledged and customizable navigation library for Jetpack Compose

A small and simple, yet fully fledged and customizable navigation library for Jetpack Compose

🛸Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.
🛸Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

A small navigation library for Jetpack Compose with state saving, backstack and animations support.

A small navigation library for Jetpack Compose with state saving, backstack and animations support.

A simple navigation library for Android 🗺️

Enro 🗺️ A simple navigation library for Android "The novices’ eyes followed the wriggling path up from the well as it swept a great meandering arc ar

🧛 Fragula is a swipe-to-dismiss extension for navigation component library for Android
🧛 Fragula is a swipe-to-dismiss extension for navigation component library for Android

Fragula is a swipe-to-dismiss extension for navigation component library for Android.

Releases(v1.1.0)
  • v1.1.0(May 27, 2020)

    Adds BriefActionHandler - handling of common message display actions. Now common brief actions for showing a toast and brief snackbar are automatically handled, and there are actions defined to send them via the VeiwModel out of the box. Instance of the snackbar can be obtained by overriding fun showBriefSnackbar. Minification enabled.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(May 9, 2020)

  • v1.0.2(May 9, 2020)

Owner
null
A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

Kaustubh Patange 88 Dec 11, 2022
Android Navigation Fragment Share Element Example: Use Share Element Transition with recyclerView Item and ViewPager2 Item.

Android-Navigation-Fragment-Share-Element-Example 说明 Android 使用Navigation导航切换Fragment中使用共享元素过渡动画的例子:将在listFragment的RecyclerView的Item共享元素过渡到pagerFragme

null 3 Sep 28, 2022
Tugas Fragment Codelab Navigation Pemrograman Mobile

AndroidTrivia - starter code Starter code for Android Kotlin Fundamentals codelab 3.1: Create and add a fragment. Introduction The AndroidTrivia app a

null 0 Nov 3, 2021
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way.

Alligator Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way. Features Any app

Artur Artikov 290 Dec 9, 2022
Navigation Component: THE BEST WAY to create navigation flows for your app

LIVE #017 - Navigation Component: A MELHOR FORMA de criar fluxos de navegação para o seu app! Código fonte do projeto criado na live #017, ensinando c

Kaique Ocanha 4 Jun 15, 2022
Memory efficient android library for managing individual fragment backstack.

fragstack : Android library for managing individual fragment backstack. An Easy to use library for managing individual fragment back stack as Instagra

Abhishesh 21 Feb 6, 2021
[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).

Simple Stack Why do I want this? To make navigation to another screen as simple as backstack.goTo(SomeScreen()), and going back as simple as backstack

Gabor Varadi 1.3k Jan 2, 2023
Animated Tab Bar is an awesome navigation extension that you can use to add cool, animated and fully customizable tab navigation in your apps

Animated Tab Bar is an awesome navigation extension that you can use to add cool, animated and fully customizable tab navigation in your apps. The extension provides handy methods and properties to change the behaviour as well as the appearance of the navigation bar.

Zain Ul Hassan 4 Nov 30, 2022
Android multi-module navigation built on top of Jetpack Navigation Compose

MultiNavCompose Android library for multi-module navigation built on top of Jetpack Navigation Compose. The goal of this library is to simplify the se

Jeziel Lago 21 Dec 10, 2022
DSC Moi University session on using Navigation components to simplify creating navigation flow in our apps to use best practices recommended by the Google Android Team

Navigation Components Navigate between destination using safe args How to use the navigation graph and editor How send data between destinations Demo

Breens Mbaka 6 Feb 3, 2022