{"id":43235518,"url":"https://github.com/johnazedo/android-boilerplate","last_synced_at":"2026-02-01T10:38:03.820Z","repository":{"id":269986698,"uuid":"909007425","full_name":"johnazedo/android-boilerplate","owner":"johnazedo","description":"A library to simplify the android development","archived":false,"fork":false,"pushed_at":"2025-05-30T11:23:41.000Z","size":211,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-13T02:26:18.627Z","etag":null,"topics":["android","android-library","boilerplate","jetpack-compose","koltin","library","mvi"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnazedo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-27T14:17:31.000Z","updated_at":"2025-05-30T11:15:09.000Z","dependencies_parsed_at":"2025-01-14T17:55:28.805Z","dependency_job_id":"48e6238d-8694-41f5-bb48-ec3a63fe405c","html_url":"https://github.com/johnazedo/android-boilerplate","commit_stats":null,"previous_names":["johnazedo/kotlin-mvvm","johnazedo/android-boilerplate"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/johnazedo/android-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnazedo%2Fandroid-boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnazedo%2Fandroid-boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnazedo%2Fandroid-boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnazedo%2Fandroid-boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnazedo","download_url":"https://codeload.github.com/johnazedo/android-boilerplate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnazedo%2Fandroid-boilerplate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28976334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T09:57:52.632Z","status":"ssl_error","status_checked_at":"2026-02-01T09:57:49.143Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","boilerplate","jetpack-compose","koltin","library","mvi"],"created_at":"2026-02-01T10:38:03.198Z","updated_at":"2026-02-01T10:38:03.815Z","avatar_url":"https://github.com/johnazedo.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Android Boilerplate Library\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nAndroid Boilerplate is a library designed to simplify the implementation of the Model-View-ViewModel (MVVM) and Model-View-Intent (MVI) architectural pattern in Kotlin-based projects. This library aims to streamline the development process by providing essential tools and components that facilitate a clean separation of concerns, promoting scalable and maintainable codebases.\n\n## How to use\n\nYou can add this library to your project using **JitPack**:\n\n1. **Add JitPack to your** `settings.gradle.kts`:\n```kotlin\ndependencyResolutionManagement {\n    repositories {\n        maven { url = uri(\"https://jitpack.io\") }\n    }\n}\n```\n2. **Add the dependency to your** `build.gradle.kts`:\n```kotlin\ndependencies {\n    implementation(\"com.github.johnazedo:android-boilerplate:Tag\")\n}\n```\nReplace Tag with the latest release version. You can find the latest version [here](https://jitpack.io/#johnazedo/android-boilerplate).\n\n## Features for XML Layout\nPackage: `android-boilerplate`\n\nConcepts:\n- State (State): Represents the current screen data (usually a data class);\n- Action (Action): Represents one-time events (navigation, dialogs, toasts, etc.);\n- UIError (UIError): For handling user-facing errors;\n- OneShotWrapper: Wrapper to prevent LiveData from emitting the same event multiple times.\n\n### ABViewModel\n\nThe ABViewModel is an abstracted base class designed to manage state, actions, and UI events in a clean and scalable way using LiveData and Kotlin's type system.\nIt is intended to be subclassed depending on your use case, providing variants:\n\n- `ABViewModel` – supports all features;\n- `ABViewModel.OnlyState` – only manages State, Navigation and Error reporting (No Action);\n- `ABViewModel.OnlyAction` – only manages Action, Navigation and Error reporting (No State);\n- `ABViewModel.Minimal` – only handles Navigation and Error reporting.\n\nIt is possible use the state feature and one time events without create a generic class for it:\n\n```kotlin\ndata class FormState(val name: String = \"\", val isLoading: Boolean = false) : State()\n\nsealed class FormAction : Action() {\n    object SubmitSuccess : FormAction()\n}\n\ndata class FormGenericError(\n    val resId: Int = R.strings.generic_error_message\n): UIError(resId)\n\nclass FormViewModel : ABViewModel\u003cFormState, FormAction\u003e(FormState()) {\n\n    fun submitForm(name: String) {\n        setState { it.copy(isLoading = true) }\n\n        // Simulate API\n        if(api.isOK()) {\n            performAction { FormAction.SubmitSuccess }\n            setState { it.copy(isLoading = false, name = name) }\n        } else {\n            showError { FormGenericError() }\n        }\n        \n    }\n}\n```\n\nTo observe the state change and one time events is necessary to use `onReceiveEvent`:\n```kotlin\noverride fun onViewCreated(view: View, savedInstanceState: Bundle?) { \n    super.onViewCreated(view, savedInstanceState)\n    onReceiveEvent(\n        viewModel, \n        handleState = ::onStateChange,\n        handleAction = ::handleAction,\n        handleError = ::handleError\n    )\n}\n\nprivate fun onStateChange(state: FormState) {\n    // TODO Use state\n}\n\nprivate fun handleAction(action: FormAction) {\n    // TODO Use action\n}\n\n// Is possible to handle errors if you use the function showError in viewModel.\n// But if you want to custom the error it possible create a action to show the error.\n// For example: FormAction.ShowError.\nprivate fun handleError(error: UIError) {\n    // TODO Handle error\n}\n```\n\nIf the screen is simple and does not have actions, or state or the both, is possible to use the ABViewModel variations\n```kotlin\n\n// To handle only with state, navigation and error handle\nclass FormViewModel : ABViewModel.OnlyState\u003cFormState\u003e(FormState())\n\n// To handle only with action, navigation and error handle\nclass FormViewModel : ABViewModel.OnlyAction\u003cFormAction\u003e()\n\n// To use only navigation and error handle\nclass FormViewModel : ABViewModel.Minimal()\n```\n\n### Navigation\n\nTo use navigation with this package is necessary to make some changes in your Main Activity. First\nis important to create a nav graph in navigation resource folder and set this graph into Main Activity layout.\n\n```xml\n\u003c!-- main_graph.xml --\u003e\n\u003cnavigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/main_graph\"\n    app:startDestination=\"@id/main_fragment\"\u003e\n\n    \u003cfragment\n        android:id=\"@+id/login_fragment\"\n        android:name=\"com.lemonade.sample.xml.LoginFragment\"\n        android:label=\"LoginFragment\"\n        /\u003e\n\n    \u003cfragment\n        android:id=\"@+id/home_fragment\"\n        android:name=\"com.lemonade.sample.xml.HomeFragment\"\n        android:label=\"HomeFragment\"\n        /\u003e\n\n    \u003cfragment\n        android:id=\"@+id/main_fragment\"\n        android:name=\"com.lemonade.sample.xml.MainFragment\"\n        android:label=\"MainFragment\"\n        /\u003e\n\n\u003c/navigation\u003e\n\n\u003c!-- main_activity.xml --\u003e\n\u003candroidx.constraintlayout.widget.ConstraintLayout \n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\u003e\n\n    \u003candroidx.fragment.app.FragmentContainerView\n        android:id=\"@+id/fragment_container\"\n        android:name=\"androidx.navigation.fragment.NavHostFragment\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        app:defaultNavHost=\"true\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:navGraph=\"@navigation/main_graph\"\n    /\u003e\n\n\u003c/androidx.constraintlayout.widget.ConstraintLayout\u003e\n```\n\nAdditionally, it is necessary to implement the `ABActivity` class in your `MainActivity`. PS: `ABActivity` extends `AppCompatActivity`:\n\n```kotlin\nclass MainActivity : ABActivity() {\n    // TODO: Implement this\n}\n\n// In Any ViewModel\nclass AnyViewModel : ABViewModel.Minimal() {\n\n    fun navigateToAny() {\n        navigateTo {\n            // Is possible to use NavOptions and Bundle. See Destination class\n            Destination(\n                destinationId = R.id.main_fragment,\n            )\n        }\n    }\n}\n```\nNow. Is possible to use `navigateTo` in any fragment viewModel linked with MainActivity.\n\nIf is needed to use more than a activity, use a Action to navigate to another activity and make the same setup for the new component.\n\n### Extension functions\n\nYou can use ViewModel.coroutineRunCatching instead withContext:\n```kotlin\n// Use this\nviewModelScope.launch {\n    coroutineRunCatching(dispatcher) { \n        // suspend fun\n    }.onSuccess { \n        // handle success\n    }.onFailure { \n        //handle error\n    }\n}\n\n// Instead\nviewModelScope.launch {\n    withContext(dispatcher) {\n        runCatching {\n            // suspend fun\n        }.onSuccess { \n            // handle success\n        }.onFailure { \n            // handle error\n        }\n    }\n}\n```\n\n\n## Features for Jetpack-Compose\nPackage: `android-boilerplate-compose`\n\nThis feature is coming soon.\n\n## Contributing\n\nContributions are welcome! If you have suggestions for improvements or new features, please open an issue or submit a pull request. For major changes, it's recommended to discuss them first by opening an issue to ensure alignment with the project's goals.\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](https://github.com/johnazedo/android-boilerplate/blob/main/LICENSE) file for more details.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnazedo%2Fandroid-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnazedo%2Fandroid-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnazedo%2Fandroid-boilerplate/lists"}