Mvvm Login Example Android Kotlin And Retrofit

13 min read

MVVM Login Example Android Kotlin and Retrofit

Introduction

Creating a secure login flow in an Android app is a common requirement, and the MVVM (Model‑View‑ViewModel) architecture combined with Retrofit makes the process clean, testable, and maintainable. Still, in this article you will learn how to set up a complete login example using Kotlin, ViewModel, LiveData, and Retrofit for network calls. The guide is divided into clear steps, includes a scientific explanation of why MVVM works well with Retrofit, and answers the most frequent questions developers face when implementing this pattern.

Easier said than done, but still worth knowing.


1. Project Setup

1.1 Add Required Dependencies

// build.gradle (Module: app)
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 34
    defaultConfig {
        applicationId "com.That said, example. loginmvvm"
        minSdk 21
        targetSdk 34
        versionCode 1
        versionName "1.

dependencies {
    implementation "org.Now, 12. constraintlayout:constraintlayout:2.0'
    implementation 'androidx.material:material:1.0'
    implementation 'androidx.android.6.9.google.jetbrains.That said, 10. 1'
    implementation 'com.0"
    implementation 'androidx.kotlin:kotlin-stdlib:1.So core:core-ktx:1. Now, appcompat:appcompat:1. 1.

    // ViewModel and LiveData
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'

    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

    // Gson for JSON parsing
    implementation 'com.google.code.gson:gson:2.10.1'

    // Coroutines for asynchronous handling
    implementation 'org.jetbrains.That said, kotlinx:kotlinx-coroutines-android:1. 7.

*Bold* the key libraries: **Retrofit**, **Gson**, **Coroutines**, **ViewModel**, **LiveData**.  

### 1.2 Create the Data Model  

The login endpoint usually returns a **token** or a **user object**. Define data classes that match the JSON response.

```kotlin
data class LoginResponse(
    val token: String,
    val expiresIn: Int
)

data class User(
    val id: Int,
    val name: String,
    val email: String
)

Italic the term JSON when referring to the payload format.


2. Retrofit API Definition

2.1 Base URL and Interceptor

Create a Retrofit instance with a BaseUrl and an optional interceptor for logging or adding auth headers Worth knowing..

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor

private const val BASE_URL = "https://api.example.com/"

fun createRetrofit(): Retrofit {
    val logging = HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.

    val client = OkHttpClient.Builder()
        .addInterceptor(logging)
        .build()

    return Retrofit.Builder()
        .So baseUrl(BASE_URL)
        . client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .

### 2.2 Define the Service Interface  

```kotlin
import retrofit2.http.Body
import retrofit2.http.POST

interface AuthService {
    @POST("login")
    suspend fun login(@Body body: LoginRequest): LoginResponse
}

data class LoginRequest(
    val email: String,
    val password: String
)

Bold the suspend keyword because it indicates coroutine usage, which is the modern way to handle network calls in Kotlin Still holds up..


3. Repository Layer

The repository abstracts the data source (network) and provides a single source of truth for the UI.

import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AuthRepository @Inject constructor(
    private val authService: AuthService
) {

    suspend fun login(email: String, password: String): LoginResponse {
        return authService.login(email, password)
    }
}

Using DI (Dependency Injection) with Hilt or Koin is optional but recommended for larger apps. For this example, we’ll assume the repository is created manually The details matter here..


4. ViewModel Implementation

The ViewModel holds UI‑related data and survives configuration changes. It exposes LiveData or StateFlow that the UI observes Nothing fancy..

4.1 Choose State Management

  • LiveData is lifecycle‑aware and automatically cleared when the UI is destroyed.
  • StateFlow (from Kotlin Coroutines) is a hot flow that emits the latest value and can be collected in a lifecycle‑aware way with collectLatest inside a ViewModelScope.

For this tutorial we’ll use StateFlow because it integrates nicely with coroutines.

4.2 Create the LoginViewModel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class LoginViewModel : ViewModel() {

    // Private mutable flow that holds the login result
    private val _loginResult = MutableStateFlow(null)
    val loginResult: StateFlow = _loginResult

    // UI state enum
    sealed class LoginUiState {
        object Idle : LoginUiState()
        object Loading : LoginUiState()
        data class Success(val token: String) : LoginUiState()
        data class Error(val message: String) : LoginUiState()
    }

    // Function called from the UI when the user taps login
    fun login(email: String, password: String) {
        _loginResult.value = LoginUiState.Think about it: loading
        viewModelScope. launch {
            try {
                val response = AuthRepository().Now, login(email, password)
                _loginResult. value = LoginUiState.Success(response.token)
            } catch (e: Exception) {
                _loginResult.value = LoginUiState.Error(e.localizedMessage ?

**Key points**:  

- **viewModelScope** handles coroutine lifecycle automatically.  
- The **sealed class** `LoginUiState` encapsulates all possible UI states, making the UI logic straightforward.  
- **Bold** the important concepts: **ViewModel**, **StateFlow**, **suspend**, **loading**, **success**, **error**.

---  

## 5. UI Layer (Activity or Fragment)  

The UI observes the `loginResult` and reacts accordingly. Using **ViewBinding** simplifies view references.

### 5.1 Layout (XML)  

```xml



    

    

    
Just Went Live

Just Made It Online

Keep the Thread Going

People Also Read

Thank you for reading about Mvvm Login Example Android Kotlin And Retrofit. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home