ViewModel – – Fácil inicio de sesión usando ViewModel de Android en Kotlin | por Ashwini Jadhav Octubre de 2020

En este tutorial, veremos cómo usar el modelo de vista para iniciar sesión en su aplicación de Android.

ViewModel: Es un puente entre la vista y el modelo (lógica empresarial). No tiene ningún rastro que View deba usar porque no tiene ninguna referencia directa a View. En principio, por tanto, ViewModel no debería conocer la vista con la que se comunica. Interactúa con el modelo y expone observables que se pueden observar en la Vista.

  1. Ir Archivo ⇒ Nuevo proyecto. .escoger Actividad vacía y continuar.
  2. Agregar dependencias: – –
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion 30
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "com.example.viewmodelimp"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation 'com.github.Zhuinden:live-event:1.0.0'
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.2.5"
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}build.gradle (project Module)

buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

3.activity_main: – – –

<?xml version="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:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint"
android:layout_width="match_parent"
android:layout_height="200dp">

<TextView
android:id="@+id/loginlogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login"
android:textColor="#000000"
android:textSize="40sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="148px"
android:padding="8dp"
android:layout_below="@id/constraint"
android:id="@+id/loginuser"
android:hint="Username"
android:drawablePadding="10dp"

/>

/>
<EditText
android:drawablePadding="10dp"

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:padding="8dp"
android:layout_marginTop="15dp"
android:layout_below="@id/loginuser"
android:id="@+id/loginpassword"
android:hint="Password"
android:inputType="textPassword"

/>

<Button
android:id="@+id/loginbtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/loginpassword"
android:layout_marginLeft="50dp"
android:layout_marginTop="15dp"
android:layout_marginRight="50dp"
android:background="@android:color/white"
android:shadowColor="@android:color/white"
android:text="LOGIN"
android:textSize="25sp" />

</RelativeLayout>

4. Actividad de inicio de sesión: – –

class LoginActivity : AppCompatActivity() {
private val viewModel by viewModels<UserViewModel>()

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

loginuser.onTextChanged {
viewModel.user.value = it.toString()
}

loginpassword.onTextChanged {
viewModel.password.value = it.toString()
}

loginbtn.setOnClickListener {
viewModel.login1()
}

viewModel.loginResult.observe(this) { result ->
when (result) {
UserViewModel.LoginResult.UserMissing -> {
Toast.makeText(
applicationContext, "Data is missing", Toast.LENGTH_LONG
).show()
loginuser.error = "Email required"
loginuser.requestFocus()
}
UserViewModel.LoginResult.PasswordMissing -> {
loginpassword.error = "Password required"
loginpassword.requestFocus()
}
UserViewModel.LoginResult.NetworkFailure -> {
//do anything
}

UserViewModel.LoginResult.Success -> {
val intent = Intent(applicationContext, HomeActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

startActivity(intent)
finish()
}
else -> {
Toast.makeText(applicationContext, "hello", Toast.LENGTH_LONG).show()
}
}
}
}

inline fun EditText.onTextChanged(crossinline textChangeListener: (String) -> Unit) {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable) {
textChangeListener(editable.toString())
}

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
}

5. UserViewModel: – –

class UserViewModel(context: Application, savedStateHandle: SavedStateHandle) : AndroidViewModel(
context
) {
sealed class LoginResult {
object UserMissing : LoginResult()

object PasswordMissing : LoginResult()

class NetworkError(val userMessage: String) : LoginResult()

object NetworkFailure : LoginResult()

object Success : LoginResult()
}

val user: MutableLiveData<String> = savedStateHandle.getLiveData("user", "")
val password: MutableLiveData<String> = savedStateHandle.getLiveData("password", "")

private val loginResultEmitter = EventEmitter<LoginResult>()
val loginResult: EventSource<LoginResult> = loginResultEmitter

fun login1() {
val email = user.value!!.toString().trim()
val password = password.value!!.toString().trim()

if (email.isEmpty()) {
loginResultEmitter.emit(LoginResult.UserMissing)
return
}

if (password.isEmpty()) {
loginResultEmitter.emit(LoginResult.PasswordMissing)
return
}
loginResultEmitter.emit(LoginResult.Success)

}
}

6: Finalmente InicioActividad

class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.home)
}
}

7. home.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="welcome"
android:textColor="@android:color/black"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

8. M.Ynifest: – –

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.viewmodelimp">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ViewModelImp">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".HomeActivity"/>
</application>

</manifest>

9: salida / capturas de pantalla: – –

1. pantalla de inicio de sesión
2. Pantalla de inicio

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *