Android Mvvm Example .If you want to know about Android Mvvm Example , then this article is for you. You will find a lot of information about Android Mvvm Example in this article. We hope you find the information useful and informative. You can find more articles on the website.

What is Android?

Android, the widely popular operating system, is the beating heart behind millions of smartphones and tablets globally. Developed by Google, Android is an open-source platform that powers a diverse range of devices, offering users an intuitive and customizable experience. With its user-friendly interface, Android provides easy access to a plethora of applications through the Google Play Store, catering to every need imaginable. From social media and gaming to productivity and entertainment, Android seamlessly integrates into our daily lives, ensuring that the world is at our fingertips. Whether you're a tech enthusiast or a casual user, Android's versatility and accessibility make it a cornerstone of modern mobile technology.

Title: Practical Example of Android MVVM Architecture: Building a Simple App

In this article, we'll walk you through a complete Android MVVM example. This will help you understand how the Model-View-ViewModel (MVVM) architecture works in a real Android app. We'll build a simple app that fetches user data from a remote API, displays it in the UI, and uses the MVVM pattern for better separation of concerns, scalability, and testability.

By the end of this tutorial, you'll be able to apply MVVM in your own Android projects and understand how to organize your app in a more modular and maintainable way.


Project Setup

For this example, we'll build an app that fetches user details from a public API. To implement MVVM, we'll use the following libraries:

  • Retrofit for networking.
  • LiveData and ViewModel for reactive data binding.
  • Room (optional) for local database storage, if you'd like to extend the app.

First, create a new Android project and add the following dependencies to your build.gradle file.

build.gradle (App-level)

dependencies {
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'androidx.room:room-runtime:2.3.0'
    implementation 'androidx.room:room-ktx:2.3.0'
    annotationProcessor 'androidx.room:room-compiler:2.3.0' // or use kapt for Kotlin
}

1. Model Layer: Defining the Data Classes

The Model is responsible for managing the data. We will define a User data class to represent the user data.

User Data Class

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

This User class will be used to parse the API response.

Retrofit API Service

We’ll use Retrofit to fetch data from an API. Let’s define a simple API interface to fetch user details.

interface ApiService {

    @GET("users/{id}")
    suspend fun getUser(@Path("id") userId: Int): User
}

Here, getUser() fetches a user’s data based on their id.

Retrofit Instance

Create a singleton for Retrofit to make network requests.

object RetrofitInstance {
    private const val BASE_URL = "https://jsonplaceholder.typicode.com/"

    val api: ApiService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}

This code initializes the Retrofit instance and provides a simple interface to make API calls.


2. ViewModel Layer: Handling Data Logic

The ViewModel is responsible for managing the UI-related data and acting as an intermediary between the Model and View. In this case, the ViewModel will fetch the user data from the ApiService and expose it to the View using LiveData.

UserViewModel

class UserViewModel : ViewModel() {

    private val _userLiveData = MutableLiveData<User>()
    val userLiveData: LiveData<User> get() = _userLiveData

    // Fetch user details from API
    fun getUser(userId: Int) {
        viewModelScope.launch {
            try {
                val user = RetrofitInstance.api.getUser(userId)
                _userLiveData.postValue(user)
            } catch (e: Exception) {
                // Handle error
                Log.e("UserViewModel", "Error fetching user data: $e")
            }
        }
    }
}

Here, the UserViewModel:

  • Exposes a LiveData<User> to the UI.
  • Uses ViewModelScope to perform asynchronous operations.
  • Fetches data using Retrofit’s getUser() method and updates the LiveData when the data is successfully fetched.

3. View Layer: UI (Activity)

The View (in this case, the Activity) displays the UI and observes changes in the ViewModel. It should never directly interact with the Model. Instead, the View simply observes data from the ViewModel and updates the UI accordingly.

UserProfileActivity (View)

class UserProfileActivity : AppCompatActivity() {

    private lateinit var userViewModel: UserViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user_profile)

        // Initialize ViewModel
        userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        // Observe the LiveData from the ViewModel
        userViewModel.userLiveData.observe(this, Observer { user ->
            // Update UI with the user data
            findViewById<TextView>(R.id.nameTextView).text = user.name
            findViewById<TextView>(R.id.emailTextView).text = user.email
        })

        // Trigger ViewModel to fetch user data
        userViewModel.getUser(1) // Fetch user with ID 1
    }
}

In the UserProfileActivity:

  • We initialize the UserViewModel using ViewModelProvider.
  • We observe the LiveData<User> from the UserViewModel. When the data changes, the Observer is triggered, and we update the UI (the TextViews for user name and email).
  • The getUser() function is called with a user ID (in this case, 1) to fetch the user data.

Layout (activity_user_profile.xml)

Here's a simple layout file to display the user details:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/nameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="User Name"
        android:textSize="18sp"/>

    <TextView
        android:id="@+id/emailTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="User Email"
        android:textSize="18sp"/>
</LinearLayout>

This layout simply contains two TextViews to display the user’s name and email.


4. Running the App

Now that we've set up the Model, ViewModel, and View, you can run the app. When the UserProfileActivity is opened, it will:

  1. Trigger the getUser() function in the UserViewModel.
  2. The ViewModel fetches user data from the API.
  3. The data is passed to the LiveData, and the UI is updated automatically with the user’s name and email.

Benefits of Using MVVM in This Example

By using MVVM in this example, you gain several advantages:

  1. Separation of Concerns: The Model, View, and ViewModel have distinct roles, making the app easier to maintain and extend.
  2. Testability: You can easily unit-test the UserViewModel without worrying about the UI components.
  3. Reactivity: LiveData automatically updates the UI whenever the data changes, making the app more responsive.
  4. Lifecycle Awareness: The ViewModel is lifecycle-aware, so it survives configuration changes like screen rotations without reloading data.

Conclusion

In this tutorial, we built a simple Android app using the MVVM architecture to fetch user data from an API and display it on the UI. By organizing your code into the Model, View, and ViewModel layers, you make your app more modular, scalable, and maintainable. You also ensure that the UI is reactive and lifecycle-aware, improving both the user experience and the quality of the code.

With MVVM, you can build more complex Android applications that are easier to test, debug, and extend, making it a perfect architecture pattern for modern Android development.