-
-
Save marciogranzotto/1c96e87484a17bd914e159b2604e6469 to your computer and use it in GitHub Desktop.
| interface LoginContracts { | |
| interface View { | |
| fun showError(message: String) | |
| } | |
| interface Presenter { | |
| fun onDestroy() | |
| fun onLoginButtonPressed(username: String, password: String) | |
| } | |
| interface Interactor { | |
| fun unregister() | |
| fun login(username: String, password: String) | |
| } | |
| interface InteractorOutput { | |
| fun onLoginSuccess(user: User) | |
| fun onLoginError(message: String) | |
| } | |
| interface Router { | |
| fun unregister() | |
| fun presentHomeScreen(user: User) | |
| } | |
| } | |
| class LoginActivity: BaseActivity, LoginContracts.View { | |
| var presenter: LoginContracts.Presenter? = null | |
| //other fields | |
| override fun onCreate() { | |
| //... | |
| presenter = LoginPresenter(this) | |
| loginButton.setOnClickListener { onLoginButtonClicked() } | |
| //... | |
| } | |
| override fun onDestroy() { | |
| presenter?.onDestroy() | |
| presenter = null | |
| super.onDestroy() | |
| } | |
| private fun onLoginButtonClicked() { | |
| presenter?.onLoginButtonClicked(usernameEditText.text, passwordEditText.text) | |
| } | |
| fun showError(message: String) { | |
| //shows the error on a dialog | |
| } | |
| } | |
| class LoginPresenter(var view: LoginContracts.View?): LoginContracts.Presenter, LoginContracts.InteractorOutput { | |
| var interactor: LoginContracts.Interactor? = LoginInteractor(this) | |
| var router: LoginContracts.Router? = LoginRouter(view as? Activity) | |
| fun onDestroy() { | |
| view = null | |
| interactor?.unregister() | |
| interactor = null | |
| router?.unregister() | |
| router = null | |
| } | |
| fun onLoginButtonPressed(username: String, password: String) { | |
| interactor?.login(username, password) | |
| } | |
| fun onLoginSuccess(user: User) { | |
| router?.goToNextScreen(user) | |
| } | |
| fun onLoginError(message: String) { | |
| view?.showError(message) | |
| } | |
| } | |
| class LoginInteractor(var output: LoginContracts.InteractorOutput?): LoginContracts.Interactor { | |
| fun unregister() { | |
| output = null | |
| } | |
| fun login(username: String, password: String) { | |
| LoginApiManager.login(username, password) | |
| ?.subscribeOn(Schedulers.io()) | |
| ?.observeOn(AndroidSchedulers.mainThread()) | |
| ?.subscribe({ | |
| //does something with the user, like saving it or the token | |
| output?.onLoginSuccess(it) | |
| }, | |
| { output?.onLoginError(it.message ?: "Error!") }) | |
| } | |
| } | |
| class LoginRouter(var activity: Activity?): LoginContracts.Router { | |
| fun unregister() { | |
| activity = null | |
| } | |
| fun presentHomeScreen(user: User) { | |
| val intent = Intent(view, HomeActivity::class.java) | |
| intent.putExtra(Constants.IntentExtras.USER, user) | |
| activity?.startActivity(intent) | |
| } | |
| } |
In this example the presenter doesn't survive to rotation, right?
I think u can use view-model instead of presenter to handle config change in a better way.
How can I implement the navigation component: https://developer.android.com/guide/navigation ?
Visit this sample project on github and medium to better understanding
A Mini Uber with Kotlin Multiplatform + VIPER Architecture + Compose Multiplatform Architecture
Overview:
View → Composable screens observing StateFlow<UiState>.
Presenter → Extends ViewModel, processes events, updates state.
Interactor → Business logic (e.g., fetch drivers, request ride).
Router → Handles navigation between screens + result passing.
Entities → Models like DriverResponse, RideRequest.
-
Navigation concerns stay separated in Router, not spread in the UI.
-
Google map implementation, state management, and challenges in the compose multipaltform
github:
https://github.com/mahdizareeii/Mini-Uber
medium:
What architecture exactly do you mean? They have Room, LiveObjects and some crappy navigation. How that solves the problem where to put Network communication for example?