GithubHelp home page GithubHelp logo

thomasbernard03 / rickandmortyjetpackcompose Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 1.15 MB

Rick and Morty native application developed using Kotlin and Jetpack Compose

Kotlin 100.00%
coil jetpack-compose koin kotlin retrofit2 room

rickandmortyjetpackcompose's Introduction

Rick And Morty Jetpack Compose

API API API

Technologies

  • Room pour la base de données (Dao, Entity, Embedded)
  • Retrofit2 pour les requètes HTTP (Interceptors)
  • Koin pour l'injection de dépendances
  • Android navigation avec NavHost
  • Coroutines
  • Preferences
  • LazyList, Async Images

Architecture générale

Couche présentation

MainActivity

La couche présentation contient toutes les features de l'application (login, main etc...). À la racine du package presentation on peut voir MainActivity. Nous utilisons une application en Single Activity. Nous auront donc une seule et unique Activité. Dans cette activité nous déclarons notre Scaffold et notre seul NavHost. C'est donc au sein de ce Scaffold que la navigation sera effectuée.

Dans cette Activity nous injectons notre navigator : Navigator, cette instance de Navigator va nous permettre d'écouter toutes les navigations effectuée dans l'application et les répercuter sur notre navController. Cette classe nous permet d'effectuer la navigation directement depuis nos ViewModels.

Nous injectons aussi notre errorHelper: ErrorHelper. Tout comme pour le navigator, nous nous abonnons à cette instance pour pouvoir afficher les messages d'erreur en utilisant le snackbarHostState de notre Scaffold. Nous avons créé ce ErrorHelper pour éviter de passer des callback dans chacun de nos screens pour afficher des messages d'erreurs.

Screen

Les screen sont des fonctions composables qui définissent l'affichage de nos écrans. Chaque Screen prend un State en paramètre et un callback onEvent(). Nous pouvons donc personnaliser nos Previews en modifiant le state. Les previews sont des fonctions composables privées situées en bas de page.

@Composable
fun LoginScreen(uiState : LoginUiState, onEvent : (LoginEvent) -> Unit){

}

UiState

Les UiState sont des dataclass contenant toutes les données de nos écrans qui peuvent changer. Toutes les propriétés de ces states doivent être immutables et doivent donc être changées en updatant le state tout entier. Les states sont modifiés dans le ViewModel de cette manière :

private val _uiState = MutableStateFlow(LoginUiState())
val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()

private fun onLogin(username : String, password : String){
    _uiState.update { it.copy(loading = false) }
}

Event

Les event sont des SealedClass qui contiennent toutes les actions que le Screen peut déclencher. Ces actions sont traités dans le ViewModel :

sealed class LoginEvent {
    data object OnAppearing : LoginEvent()
    data class OnLogin(val username : String, val password : String) : LoginEvent()
}

fun onEvent(event : LoginEvent){
    when(event){
        is LoginEvent.OnAppearing -> onAppearing()
        is LoginEvent.OnLogin -> onLogin(event.username, event.password)
    }
}

ViewModel

Le ViewModel est la pièce centrale de la couche présentation. Ces classes handle traitent tous les évenements propagés par l'interface utilisateur (Screen) et mettent à jour le state (UiState). Pour certaines méthodes, nous pouvons lancer des coroutines en utilisant le viewModelScope. Cela permet d'executer de longues tâches sans bloquer l'interface utilisateur.

Package components

Le package components ne contient que des fonctions composables. Ces dernières doivent être le plus simple et réutilisables possibles. Ces composants peuvent être triés par feature si ils ne sont utilisés que dans une seule et même feature. Ces composants doivent avoir des preview, cela permettra de les reconnaitre et de les tester très facilement.

Couche domain

La couche domain est séparée en 3 packages principaux :

Models

Les models sont des classes contenant les données prêtes pour l'affichage. Elle ne doivent pas contenir d'annotations dépendantes de la couche data.

Repositories

Ce packages contient uniquement les interfaces de nos Repositories (Couche Data). Ces interfaces doivent définir le comportement de nos implémentations

UseCases

Les UseCases contiennent les cas d'utilisation de notre application, c'est notre logique métier. Dans nos usecases nous injections nos repositories (Leurs interfaces). Ces UsesCases doivent surcharger l'opérateur invoke. Ils contiennent donc une seule méthode publique.

class LoginUserUseCase(){
    suspend operator fun invoke(username : String, password : String){ }
}

De cette manière nous pouvons alors appeler notre use case comme cela :

// Ici notre use case est injecté dans notre ViewModel
val loginResult = loginUseCase(username, password)

La plupart des usecases retournent un Type Resource. Cela permet de gérer facilement les erreurs dans nos ViewModels et d'afficher des messages d'erreurs parlant pour l'utilisateur. Les uses cases ne lèvent donc pas d'exception. Ils doivent catcher ces dernières.

Couche data

La couche data contient 3 packages.

Repositories

Ce package contient l'implémentation des repositories de notre couche domain. Ces repositories sont suffixés de Impl. Dans ces repositories nous injectons nos DAO et notre ApiService. Chaque méthode dans un repoistories peut lever des Exceptions.

Local

Le package local contient toutes nos sources de données locales.

DAO

Les DAO (Data Access Object) sont des méthodes d'accès à nos données locales. Avec Room, ces classes doivent être annontés de @Dao. Toutes les méthodes dans un DAO doivent être suspend pour ne pas bloquer l'interface utilisateur. Exemple de DAO CharacterDao :

@Dao
interface CharacterDao {
    @Query("SELECT * FROM characterentity WHERE id = :id")
    suspend fun getCharacter(id: Long): CharacterEntity
}

Entities

Les Entities représentent notre modèle de base de données. Elles possèdent toutes les annotations nécéssaires du Framework pour par exemple créer des index et des clés primaires. Exemple d'entité CharacterEntity

@Entity
data class CharacterEntity(
    @PrimaryKey
    val id: Long,
    val name: String,
    val status: Status,
    val species: String,
    val type: String,
    val image: String,
    val gender: Gender,
    val url : String,
)

Commons

La couche commons contient toutes les méthodes utilisables à travers toutes les couches de notre application.

Extensions

Le package extensions contient toutes les méthodes d'extensions. Exemple de méthode d'extensions DateExtension :

fun Date.toPrettyDate() : String {
    val dateFormatter = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH)
    return dateFormatter.format(this)
}

Helpers

Les helpers sont des classes permettant de faciliter certaines opérations, comme par exemple récupérer une traduction, afficher une snackbar, réaliser une navigation. Helpers. Tous ces helpers doivent avoir une interface et une implémentation.

rickandmortyjetpackcompose's People

Contributors

thomasbernard03 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.