đź•’ Mini-CronĂłmetro en Android con Kotlin y Coroutines (Ejercicio paso a paso)
En esta entrada te propongo un ejercicio práctico y guiado para Android en Kotlin, donde construirás una app sencilla de un cronómetro progresivo usando Coroutines. Es una versión simplificada del clásico ejercicio con múltiples cronos.
Ideal si estás aprendiendo Android y quieres practicar:
- Interfaces con
EditText,TextViewyButton - Uso de
Coroutinespara tareas asĂncronas - LĂłgica básica de control y validaciĂłn
🎯 ¿Qué vamos a hacer?
Una app que permita al usuario:
- Ingresar un número máximo de segundos
- Iniciar el conteo desde cero hasta ese nĂşmero
- Detenerlo o reiniciarlo en cualquier momento
Todo esto se mostrará en una interfaz limpia, sin complicaciones.
đź§° Requisitos
- Android Studio actualizado
- Kotlin como lenguaje
- SDK mĂnimo: 21 (Android 5.0 Lollipop)
- Coroutines habilitadas
1. đź› Crear el proyecto
- Abre Android Studio
- Selecciona New Project > Empty Activity
- Nombra el proyecto
MiniCronometro - Elige Kotlin como lenguaje y
minSdk 21
2. ⚙️ Configurar dependencias
Abre tu archivo build.gradle (Module: app) y agrega estas lĂneas si no están:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
}
Luego sincroniza tu proyecto.
3. đź§© Crear la interfaz (activity_main.xml)
Copia esto dentro de tu archivo res/layout/activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp"
android:orientation="vertical"
android:gravity="center_horizontal">
<EditText
android:id="@+id/editMax"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Máximo en segundos"
android:inputType="number" />
<TextView
android:id="@+id/txtCounter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="64sp"
android:layout_marginTop="24dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginTop="24dp">
<Button
android:id="@+id/btnStart"
android:text="Iniciar" />
<Button
android:id="@+id/btnStop"
android:text="Detener"
android:layout_marginStart="8dp" />
<Button
android:id="@+id/btnReset"
android:text="Reiniciar"
android:layout_marginStart="8dp" />
</LinearLayout>
</LinearLayout>
4. đź§ LĂłgica en Kotlin (MainActivity.kt)
Reemplaza el contenido de MainActivity.kt con este:
class MainActivity : AppCompatActivity() {
private lateinit var txtCounter: TextView
private var job: Job? = null
private var current = 0
private var max = 0
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editMax = findViewById<EditText>(R.id.editMax)
txtCounter = findViewById(R.id.txtCounter)
val btnStart = findViewById<Button>(R.id.btnStart)
val btnStop = findViewById<Button>(R.id.btnStop)
val btnReset = findViewById<Button>(R.id.btnReset)
btnStart.setOnClickListener {
max = editMax.text.toString().toIntOrNull() ?: 0
if (max in 1..9999) {
startCounter()
} else {
editMax.error = "Introduce un número válido (1 a 9999)"
}
}
btnStop.setOnClickListener {
job?.cancel()
}
btnReset.setOnClickListener {
job?.cancel()
current = 0
txtCounter.text = "0"
}
}
private fun startCounter() {
job?.cancel()
job = scope.launch {
while (current < max) {
delay(1000)
current++
txtCounter.text = current.toString()
}
}
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()
}
}
đź§Ş Prueba final
- Escribe un nĂşmero (por ejemplo, 10)
- Pulsa Iniciar
- Verás cómo aumenta el contador cada segundo
- Puedes detener o reiniciar en cualquier momento
đź§± Ideas para ampliarlo
- Agregar un
ProgressBar - Notificación cuando llegue al máximo
- Vibrar o reproducir sonido al finalizar
- Guardar estado usando
ViewModel
âś… ConclusiĂłn
Este mini-ejercicio te permite entender cómo usar coroutines para manejar tareas temporizadas sin bloquear la interfaz de usuario. Si ya te manejas con este, ¡puedes animarte a hacer un multicronómetro con RecyclerView como el del ejemplo más avanzado!
ÂżTe gustarĂa que subiera este cĂłdigo completo a GitHub? ÂżQuieres un vĂdeo paso a paso?
Déjamelo en los comentarios 👇
