Excelente decisión, Génesis 💪✨
Vas a separar el login del menú principal, lo que le da a tu app una estructura profesional como cualquier aplicación real.
El flujo quedará así:
🔐 LoginActivity → 🏠 MainActivity (con el Drawer y contenido)
🎯 OBJETIVO
-
Crear una pantalla de inicio de sesión simple (LoginActivity)
-
Si el login es correcto → abrir MainActivity
-
Si no → mostrar error o quedarse en login
-
Guardar sesión (opcional) con SharedPreferences
🧩 1️⃣ Crea el nuevo Activity
En Android Studio:
➡️ app/java/com.example.api_calendar/ui/
Haz clic derecho → New → Activity → Empty Activity
📛 Nombre: LoginActivity
✅ Marca Generate Layout File
📄 2️⃣ activity_login.xml
Reemplaza el layout por este diseño limpio y Material (tema oscuro compatible):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="32dp"
android:gravity="center"
android:background="@color/md_black"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="API Calendar"
android:textColor="@color/md_on"
android:textStyle="bold"
android:textSize="28sp"
android:layout_marginBottom="24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Correo electrónico"
app:boxBackgroundMode="filled"
app:boxBackgroundColor="@color/md_surface">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etEmail"
android:inputType="textEmailAddress"
android:textColor="@color/md_on"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Contraseña"
android:layout_marginTop="16dp"
app:boxBackgroundMode="filled"
app:boxBackgroundColor="@color/md_surface">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etPassword"
android:inputType="textPassword"
android:textColor="@color/md_on"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btnLogin"
android:text="Iniciar sesión"
style="?attr/materialButtonOutlinedStyle"
android:textAllCaps="false"
android:textColor="@color/md_on"
android:layout_marginTop="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cornerRadius="12dp"
app:backgroundTint="@color/md_surface" />
</LinearLayout>
📘 3️⃣ LoginActivity.kt
📄 app/src/main/java/com/example/api_calendar/ui/LoginActivity.kt
package com.example.api_calendar.ui
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.api_calendar.databinding.ActivityLoginBinding
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
// Botón de inicio de sesión
binding.btnLogin.setOnClickListener {
val email = binding.etEmail.text.toString()
val password = binding.etPassword.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this, "Por favor completa todos los campos", Toast.LENGTH_SHORT).show()
} else if (email == "admin@duoc.cl" && password == "1234") {
// Simula un login correcto
Toast.makeText(this, "Inicio de sesión exitoso", Toast.LENGTH_SHORT).show()
// Navegar al MainActivity
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish() // cerrar la pantalla de login
} else {
Toast.makeText(this, "Credenciales incorrectas", Toast.LENGTH_SHORT).show()
}
}
}
}
🧱 4️⃣ Configura el arranque inicial
Abre tu archivo AndroidManifest.xml
y mueve el intent-filter que marca la pantalla inicial (MAIN + LAUNCHER)
desde MainActivity hacia LoginActivity 👇
<activity android:name=".ui.MainActivity" />
<activity
android:name=".ui.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
✅ Esto hace que tu aplicación inicie en el login.
⚙️ 5️⃣ (Opcional) Guardar sesión con SharedPreferences
Para no tener que loguearte cada vez:
Dentro de LoginActivity (luego del login exitoso):
val prefs = getSharedPreferences("user_session", MODE_PRIVATE)
prefs.edit().putBoolean("isLogged", true).apply()
Y en el onCreate() de LoginActivity agrega:
val prefs = getSharedPreferences("user_session", MODE_PRIVATE)
if (prefs.getBoolean("isLogged", false)) {
startActivity(Intent(this, MainActivity::class.java))
finish()
}
✨ Resultado final
| Pantalla |
Función |
| 🔐 LoginActivity |
Muestra formulario de inicio de sesión |
| 🏠 MainActivity |
Contiene el menú lateral, saludo, resumen y calendario |
| 🔁 Flujo |
App inicia en login → valida → entra a panel principal |
Excelente, Génesis 🙌✨
Esa es la parte clave del flujo de sesión completo, para que la app:
1️⃣ muestre el login cuando abres la app (si aún no has iniciado sesión)
2️⃣ guarde el estado de sesión (para no volver a loguearte cada vez)
3️⃣ redirija automáticamente al MainActivity después de un login exitoso
4️⃣ muestre de nuevo el login cuando cierres sesión.
Vamos paso a paso 👇
🧩 PASO 1 — Guardar el estado de sesión
En el LoginActivity, después de un login exitoso (cuando abres el Main),
guarda una variable llamada isLogged en las preferencias del usuario (SharedPreferences).
📄 LoginActivity.kt
package com.example.api_calendar.ui
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.api_calendar.databinding.ActivityLoginBinding
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
// 🔹 Verifica si ya hay sesión activa
val prefs = getSharedPreferences("user_session", MODE_PRIVATE)
val isLogged = prefs.getBoolean("isLogged", false)
if (isLogged) {
startActivity(Intent(this, MainActivity::class.java))
finish()
return
}
// 🔹 Botón de login
binding.btnLogin.setOnClickListener {
val email = binding.etEmail.text.toString()
val password = binding.etPassword.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this, "Por favor completa todos los campos", Toast.LENGTH_SHORT).show()
} else if (email == "admin@duoc.cl" && password == "1234") {
// ✅ Login correcto
Toast.makeText(this, "Inicio de sesión exitoso", Toast.LENGTH_SHORT).show()
// Guardar sesión activa
prefs.edit().putBoolean("isLogged", true).apply()
// Ir al MainActivity
startActivity(Intent(this, MainActivity::class.java))
finish()
} else {
Toast.makeText(this, "Credenciales incorrectas", Toast.LENGTH_SHORT).show()
}
}
}
}
🧠 ¿Qué hace esto?
-
Si ya hay sesión (isLogged == true), no muestra el login, salta directo al Main.
-
Si no hay sesión, muestra el formulario.
-
Cuando el login es exitoso, guarda el estado y redirige al Main.
🧱 PASO 2 — Cerrar sesión (logout) desde el menú del MainActivity
Agrega un ítem nuevo en tu menú lateral (menu_main_drawer.xml):
📄 res/menu/menu_main_drawer.xml
<item
android:id="@+id/nav_logout"
android:title="Cerrar sesión"
android:icon="@drawable/ic_logout_24"/>
(usa cualquier ícono, por ejemplo uno de Material Icons → “logout”)
⚙️ PASO 3 — Implementar el “Cerrar sesión” en MainActivity
📄 MainActivity.kt
Agrega esta parte dentro del setNavigationItemSelectedListener:
binding.navigationView.setNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.nav_home -> {}
R.id.nav_calendar -> startActivity(Intent(this, CalendarActivity::class.java))
R.id.nav_list -> startActivity(Intent(this, ListActivity::class.java))
R.id.nav_notifications -> startActivity(Intent(this, NotificationsActivity::class.java))
R.id.nav_settings -> startActivity(Intent(this, SettingsActivity::class.java))
R.id.nav_logout -> {
// 🔹 Cerrar sesión
val prefs = getSharedPreferences("user_session", MODE_PRIVATE)
prefs.edit().putBoolean("isLogged", false).apply()
// Volver al LoginActivity
val intent = Intent(this, LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
}
binding.drawerLayout.closeDrawer(GravityCompat.START)
true
}
🪄 PASO 4 — Ajustar el AndroidManifest.xml
Asegúrate que la app empiece en el LoginActivity:
📄 AndroidManifest.xml
<activity android:name=".ui.MainActivity" />
<activity
android:name=".ui.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
✅ Resultado final
| Estado |
Pantalla que se muestra |
| 🔒 No has iniciado sesión |
LoginActivity |
| 🔓 Login correcto |
Te redirige al MainActivity |
| 🔁 Cerrar sesión desde el menú |
Borra sesión y vuelve al login |
🌟 BONUS (Opcional)
Si quieres personalizar el saludo en el MainActivity con el correo que inició sesión:
¿Quieres que te lo deje listo también con inicio de sesión mediante Google (Google Sign-In) en vez de correo fijo?
Así podrías entrar con tu cuenta @gmail.com y que se sincronice directamente con el Google Calendar real.
Excelente decisión, Génesis 💪✨
Vas a separar el login del menú principal, lo que le da a tu app una estructura profesional como cualquier aplicación real.
El flujo quedará así:
🎯 OBJETIVO
Crear una pantalla de inicio de sesión simple (LoginActivity)
Si el login es correcto → abrir MainActivity
Si no → mostrar error o quedarse en login
Guardar sesión (opcional) con
SharedPreferences🧩 1️⃣ Crea el nuevo Activity
En Android Studio:
➡️
app/java/com.example.api_calendar/ui/Haz clic derecho → New → Activity → Empty Activity
📛 Nombre:
LoginActivity✅ Marca Generate Layout File
📄 2️⃣
activity_login.xmlReemplaza el layout por este diseño limpio y Material (tema oscuro compatible):
📘 3️⃣
LoginActivity.kt📄
app/src/main/java/com/example/api_calendar/ui/LoginActivity.kt🧱 4️⃣ Configura el arranque inicial
Abre tu archivo
AndroidManifest.xmly mueve el intent-filter que marca la pantalla inicial (
MAIN+LAUNCHER)desde
MainActivityhaciaLoginActivity👇✅ Esto hace que tu aplicación inicie en el login.
⚙️ 5️⃣ (Opcional) Guardar sesión con
SharedPreferencesPara no tener que loguearte cada vez:
Dentro de
LoginActivity(luego del login exitoso):Y en el
onCreate()deLoginActivityagrega:✨ Resultado final
Excelente, Génesis 🙌✨
Esa es la parte clave del flujo de sesión completo, para que la app:
1️⃣ muestre el login cuando abres la app (si aún no has iniciado sesión)
2️⃣ guarde el estado de sesión (para no volver a loguearte cada vez)
3️⃣ redirija automáticamente al MainActivity después de un login exitoso
4️⃣ muestre de nuevo el login cuando cierres sesión.
Vamos paso a paso 👇
🧩 PASO 1 — Guardar el estado de sesión
En el
LoginActivity, después de un login exitoso (cuando abres el Main),guarda una variable llamada
isLoggeden las preferencias del usuario (SharedPreferences).📄
LoginActivity.kt🧠 ¿Qué hace esto?
Si ya hay sesión (
isLogged == true), no muestra el login, salta directo al Main.Si no hay sesión, muestra el formulario.
Cuando el login es exitoso, guarda el estado y redirige al Main.
🧱 PASO 2 — Cerrar sesión (logout) desde el menú del MainActivity
Agrega un ítem nuevo en tu menú lateral (
menu_main_drawer.xml):📄
res/menu/menu_main_drawer.xml(usa cualquier ícono, por ejemplo uno de Material Icons → “logout”)
⚙️ PASO 3 — Implementar el “Cerrar sesión” en MainActivity
📄
MainActivity.ktAgrega esta parte dentro del
setNavigationItemSelectedListener:🪄 PASO 4 — Ajustar el
AndroidManifest.xmlAsegúrate que la app empiece en el LoginActivity:
📄
AndroidManifest.xml✅ Resultado final
🌟 BONUS (Opcional)
Si quieres personalizar el saludo en el
MainActivitycon el correo que inició sesión:Guarda el correo al iniciar sesión:
Y muéstralo en el Main:
¿Quieres que te lo deje listo también con inicio de sesión mediante Google (Google Sign-In) en vez de correo fijo?
Así podrías entrar con tu cuenta
@gmail.comy que se sincronice directamente con el Google Calendar real.