0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Hướng Dẫn Chi Tiết Để Trở Thành Lập Trình Viên Android Sử Dụng Mô Hình MVVM

Đăng vào 1 tuần trước

• 6 phút đọc

Giới Thiệu Về Mô Hình MVVM Trong Phát Triển Ứng Dụng Android

Trong phát triển ứng dụng Android, mô hình MVVM (Model-View-ViewModel) là một trong những kiến trúc phổ biến giúp tách biệt rõ ràng giữa giao diện người dùng và logic xử lý dữ liệu. Dưới đây là phân tích chi tiết về từng thành phần trong mô hình MVVM:

Các Thành Phần Chính

Model

Model là nơi lưu trữ và quản lý dữ liệu của ứng dụng. Nó có thể lấy dữ liệu từ nhiều nguồn khác nhau nhưng không thực hiện bất kỳ giao tiếp trực tiếp nào với View.

View

View đại diện cho giao diện người dùng của ứng dụng. Đây là nơi hiển thị dữ liệu nhưng không chứa logic xử lý. View quan sát ViewModel để cập nhật thông tin khi cần thiết.

ViewModel

ViewModel giữ vai trò trung gian, quản lý dữ liệu và tương tác giữa Model và View. Nó cho phép View quan sát các thay đổi trong dữ liệu mà không cần quan tâm đến nơi dữ liệu được tạo ra.

Sự Khác Biệt Giữa MVVM Và MVP

Mô hình MVP (Model-Presenter-View) cũng giống như MVVM ở điểm tổ chức mã nguồn, nhưng có một số điểm khác biệt quan trọng. Trong khi Presenter trong MVP giữ tham chiếu đến View, ViewModel trong MVVM không giữ tham chiếu đó. Điều này giúp ViewModel độc lập hơn và giảm thiểu nguy cơ rò rỉ bộ nhớ.

Cài Đặt MVVM Trong Một Dự Án Android

Dưới đây là hướng dẫn từng bước để cài đặt MVVM trong ứng dụng Android:

Thêm Thư Viện Cần Thiết

Đầu tiên, thêm các thư viện dưới đây vào build.gradle của dự án:

gradle Copy
implementation 'com.amitshekhar.android:rx2-android-networking:1.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.2.18'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

Định Nghĩa Model

Tạo một lớp dữ liệu cho user như sau:

kotlin Copy
import com.google.gson.annotations.SerializedName

data class User(
    @SerializedName("id") val id: Int = 0,
    @SerializedName("name") val name: String = "",
    @SerializedName("email") val email: String = "",
    @SerializedName("avatar") val avatar: String = ""
)

Tạo ViewModel

kotlin Copy
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.demomvvm.data.model.User
import com.example.demomvvm.data.repository.MainRepository
import com.mindorks.framework.mvvm.utils.Resource
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

class MainViewModel(private val mainRepository: MainRepository) : ViewModel() {
    private val users = MutableLiveData<Resource<List<User>>>()
    private val compositeDisposable = CompositeDisposable()

    init {
        fetchUsers()
    }

    private fun fetchUsers() {
        users.postValue(Resource.loading(null))
        compositeDisposable.add(
            mainRepository.getUsers()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ userList ->
                    users.postValue(Resource.success(userList))
                }, { throwable ->
                    users.postValue(Resource.error("Something Went Wrong", null))
                })
        )
    }

    override fun onCleared() {
        super.onCleared()
        compositeDisposable.dispose()
    }

    fun getUsers(): LiveData<Resource<List<User>>> {
        return users
    }
}

Tạo View (Activity)

kotlin Copy
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.demomvvm.R
import com.example.demomvvm.data.api.ApiHelper
import com.example.demomvvm.data.api.ApiServiceImpl
import com.example.demomvvm.data.model.User
import com.example.demomvvm.base.ViewModelFactory
import com.example.demomvvm.adapter.MainAdapter
import com.example.demomvvm.viewmodel.MainViewModel
import com.mindorks.framework.mvvm.utils.Status
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private lateinit var mainViewModel: MainViewModel
    private lateinit var adapter: MainAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setupUI()
        setupViewModel()
        setupObserver()
    }

    private fun setupUI() {
        recyclerView.layoutManager = LinearLayoutManager(this)
        adapter = MainAdapter(arrayListOf())
        recyclerView.addItemDecoration(
            DividerItemDecoration(
                recyclerView.context,
                (recyclerView.layoutManager as LinearLayoutManager).orientation
            )
        )
        recyclerView.adapter = adapter
    }

    private fun setupObserver() {
        mainViewModel.getUsers().observe(this, Observer {
            when (it.status) {
                Status.SUCCESS -> {
                    progressBar.visibility = View.GONE
                    it.data?.let { users -> renderList(users) }
                    recyclerView.visibility = View.VISIBLE
                }
                Status.LOADING -> {
                    progressBar.visibility = View.VISIBLE
                    recyclerView.visibility = View.GONE
                }
                Status.ERROR -> {
                    progressBar.visibility = View.GONE
                    Toast.makeText(this, it.message, Toast.LENGTH_LONG).show()
                }
            }
        })
    }

    private fun renderList(users: List<User>) {
        adapter.addData(users)
        adapter.notifyDataSetChanged()
    }

    private fun setupViewModel() {
        mainViewModel = ViewModelProviders.of(
            this,
            ViewModelFactory(ApiHelper(ApiServiceImpl()))
        ).get(MainViewModel::class.java)
    }
}

XML Layout

Cuối cùng, đừng quên thêm quyền truy cập Internet vào file AndroidManifest.xml:

xml Copy
<uses-permission android:name="android.permission.INTERNET"/>

Kết Luận

Như vậy, bài viết đã cung cấp cái nhìn tổng quan về mô hình MVVM và cách triển khai nó trong ứng dụng Android. Trong các bài tiếp theo, chúng tôi sẽ hướng dẫn các bạn xây dựng ứng dụng xem thời tiết với coroutines và flow, điều này sẽ mang lại nhiều kiến thức bổ ích trong lập trình đa luồng trên Android. Hãy theo dõi nhé!

Tham Khảo

JournalDev - Hướng Dẫn MVVM trên Android
GitHub Code Demo
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào