Adapun Leisure API saya ambil dari web site https://reqres.in sebagai base URL pada finish level /api/login yang mana JSON request frame berupa e-mail dan password, sedangkan server akan memberikan balasan (reaction) dengan mengirimkan token jika login berhasil.
Oke langsung saja buat sebuah undertaking android menggunakan Android Studio. Disini saya gunakan template Empty Challenge dan minimal SDK 24 Android 7.0 (Nougat).
Menambahkan Dependency
Sesaat setelah undertaking selesai dibuild oleh Gradle, tambahkan dependency HTTP Consumer bernama retrofit beserta converter jsonnya. Buka construct.gradle (Module: app) dan tambahkan 2 baris berikut pada bagian dependencies:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Membuat Programs
Agar struktur program terlihat lebih rapi dan memudahkan dalam pengembangan di masa yang akan datang, buat beberapa applications. Disini saya buat beberapa bundle baru seperti: fashions, repositories, products and services, dan viewmodels. Di dalam bundle fashions sendiri saya tambahkan 2 bundle bernama requests dan responses.
Membuat LoginRequest dan LoginResponse
Hal pertama yang biasanya saya lakukan dalam pengembangan aplikasi android adalah dengan merepresentasikan knowledge dalam bentuk style. Type pertama yang coba kita implementasikan ialah LoginRequest yang disimpan bundle fashions/requests:
bundle com.melonkoding.androidmvvmarchitecture.fashions.requests;public magnificence LoginRequest {
personal String e-mail, password;
public LoginRequest(String e-mail, String password) {
this.e-mail = e-mail;
this.password = password;
}
}
Type kedua yaitu LoginResponse yang ditulis pada bundle fashions/responses:
bundle com.melonkoding.androidmvvmarchitecture.fashions.responses;public magnificence LoginResponse {
personal String token;
public LoginResponse(String token) {
this.token = token;
}
public String getToken() {
go back token;
}
}
Membuat RetrofitClient dan LoginService
Selanjutnya yaitu membuat sebuah kelas bernama RetrofitClient yang bertugas melakukan instansiasi pada kelas Retrofit dan dibuat dengan menerapkan singleton trend. Kelas ini ditulis di dalam bundle bernama products and services:
bundle com.melonkoding.androidmvvmarchitecture.products and services;import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public magnificence RetrofitClient {
personal static Retrofit example;
public static synchronized Retrofit getInstance() {
if (example == null) {
example = new Retrofit.Builder()
.baseUrl("https://reqres.in")
.addConverterFactory(GsonConverterFactory.create())
.construct();
}
go back example;
}
}
Berikutnya yaitu sebuah interface bernama LoginService:
bundle com.melonkoding.androidmvvmarchitecture.products and services;import com.melonkoding.androidmvvmarchitecture.fashions.requests.LoginRequest;
import com.melonkoding.androidmvvmarchitecture.fashions.responses.LoginResponse;
import retrofit2.Name;
import retrofit2.http.Frame;
import retrofit2.http.POST;
public interface LoginService {
@POST("/api/login")
Name<LoginResponse> login(@Frame LoginRequest loginRequest);
}
Membuat LoginRepository
Dilanjutkan dengan membuat LoginRepository di dalam bundle repositories. Kelas ini bertanggungjawab untuk berinteraksi (request/reaction) secara langsung terhadap knowledge pada server/api.
bundle com.melonkoding.androidmvvmarchitecture.repositories;import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.melonkoding.androidmvvmarchitecture.fashions.requests.LoginRequest;
import com.melonkoding.androidmvvmarchitecture.fashions.responses.LoginResponse;
import com.melonkoding.androidmvvmarchitecture.products and services.LoginService;
import com.melonkoding.androidmvvmarchitecture.products and services.RetrofitClient;
import retrofit2.Name;
import retrofit2.Callback;
import retrofit2.Reaction;
public magnificence LoginRepository {
personal LoginService loginService;
public LoginRepository() {
loginService = RetrofitClient.getInstance().create(LoginService.magnificence);
}
public LiveData<LoginResponse> login(LoginRequest loginRequest) {
MutableLiveData<LoginResponse> knowledge = new MutableLiveData<>();
loginService.login(loginRequest).enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Name<LoginResponse> name, Reaction<LoginResponse> reaction) {
if (reaction.isSuccessful()) {
knowledge.setValue(reaction.frame());
} else {
knowledge.setValue(null);
}
}
@Override
public void onFailure(Name<LoginResponse> name, Throwable t) {
knowledge.setValue(null);
}
});
go back knowledge;
}
}
Pada kelas ini terdapat sebuah way bernama login yang melewatkan parameter bertipe LoginRequest dan mengembalikan knowledge dalam tipe LiveData<LoginResponse>.
Membuat LoginViewModel
Kelas LoginViewModel “menjembatani” antara View (Task/Fragment) dengan Type, sehingga tidak ada dan memang tidak diperbolehkan sebuah view mengakses langsung sebuah style pada arsitektur MVVM.
bundle com.melonkoding.androidmvvmarchitecture.viewmodels;import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.melonkoding.androidmvvmarchitecture.fashions.requests.LoginRequest;
import com.melonkoding.androidmvvmarchitecture.fashions.responses.LoginResponse;
import com.melonkoding.androidmvvmarchitecture.repositories.LoginRepository;
public magnificence LoginViewModel extends ViewModel {
personal LoginRepository loginRepository;
public LoginViewModel() {
loginRepository = new LoginRepository();
}
public LiveData<LoginResponse> login(LoginRequest loginRequest) {
go back loginRepository.login(loginRequest);
}
}
Membuat View
View yang terlibat disini adalah sebuah job bernama MainActivity. Karena secara default kelas ini sudah dibuatkan oleh Android studio, maka kita cukup memodifikasinya saja.
Yang perlu kita persiapkan yaitu structure dari job ini yang terletak pada res/layouts/activity_main.xml. Ubah menjadi seperti ini:
<?xml model="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:equipment="http://schemas.android.com/equipment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
equipment:context=".MainActivity"><EditText
android:identity="@+identity/et_email"
android:inputType="textEmailAddress"
android:trace="@string/enter_your_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:identity="@+identity/et_password"
android:inputType="textPassword"
android:trace="@string/enter_your_password"
android:layout_below="@identity/et_email"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:identity="@+identity/btn_login"
android:textual content="@string/login"
android:layout_below="@identity/et_password"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ProgressBar
android:identity="@+identity/pb_progress"
android:layout_centerInParent="true"
android:visibility="long past"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Tujuannya menyediakan sebuah “shape” bagi consumer untuk memasukkan e-mail dan password.
Kemudian pada MainActivity disesuaikan menjadi seperti ini:
bundle com.melonkoding.androidmvvmarchitecture;import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.os.Package deal;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.melonkoding.androidmvvmarchitecture.fashions.requests.LoginRequest;
import com.melonkoding.androidmvvmarchitecture.viewmodels.LoginViewModel;
public magnificence MainActivity extends AppCompatActivity {
@Override
secure void onCreate(Package deal savedInstanceState) {
tremendous.onCreate(savedInstanceState);
setContentView(R.structure.activity_main);
EditText e-mail = findViewById(R.identity.et_email);
EditText password = findViewById(R.identity.et_password);
Button button = findViewById(R.identity.btn_login);
ProgressBar progressBar = findViewById(R.identity.pb_progress);
LoginViewModel loginViewModel = new ViewModelProvider(this).get(LoginViewModel.magnificence);
button.setOnClickListener(view -> {
if ((e-mail.getText().toString().trim().period() == 0) || (password.getText().toString().trim().period() == 0)) {
Toast.makeText(this, "Please fill e-mail and password fields first!", Toast.LENGTH_SHORT).display();
} else {
progressBar.setVisibility(View.VISIBLE);
LoginRequest loginRequest = new LoginRequest(e-mail.getText().toString(), password.getText().toString());
loginViewModel.login(loginRequest).practice(this, loginResponse -> {
if (loginResponse != null) {
progressBar.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "You are logged in with token: "+ loginResponse.getToken(), Toast.LENGTH_SHORT).display();
}
});
}
});
}
}
Menambahkan Permissions
Sebelum tahap pengujian dilakukan, pastikan untuk menambahkan permissions INTERNET pada AndroidManifest.xml:
<uses-permission android:identify="android.permission.INTERNET"/>
Itulah tadi contoh penerapan arsitektur MVVM (Type View ViewModel) pada Aplikasi Android (Java) untuk kasus Login. Complete supply code dapat diunduh pada tautan github saya: https://github.com/reeyanto/android-java-mvvm-architecture. Jika bermanfaat, silakan berikan stars atau observe akun saya. Terima kasih 🙂