1 Commits

Autor SHA1 Mensaje Fecha
ale
15f4d2eead add widget
Algunas comprobaciones han fallado
Build & Publish APK Release / build (push) Failing after 6m8s
Signed-off-by: ale <ale@manalejandro.com>
2026-03-01 00:02:40 +01:00
Se han modificado 20 ficheros con 895 adiciones y 2 borrados

Ver fichero

@@ -34,6 +34,7 @@
| 🔊 **Sonido configurable** | Activa o desactiva el sonido de las notificaciones |
| 🌐 **Multiidioma** | 8 idiomas: Español · English · 中文 · Français · Deutsch · Português · 日本語 · 한국어 |
| 🎨 **Material Design 3** | Interfaz moderna con gradientes, colores vibrantes y soporte edge-to-edge |
| 🟣 **Widget** | Widget de escritorio que muestra la tarea activa y una meta aleatoria |
---
@@ -184,6 +185,7 @@ El idioma se selecciona desde **Configuración → Idioma** y se aplica instant
- [x] Ciclo de días configurable
- [x] Multiidioma (8 idiomas)
- [x] Sonido configurable independiente del canal Android
- [x] Widget de pantalla de inicio
- [ ] Estadísticas de cumplimiento
- [ ] Widget de pantalla de inicio
- [ ] Backup en la nube

Ver fichero

@@ -27,6 +27,21 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Widget -->
<receiver
android:name=".widget.MotivameWidget"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.manalejandro.motivame.WIDGET_REFRESH" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/motivame_widget_info" />
</receiver>
</application>
</manifest>

Ver fichero

@@ -5,6 +5,7 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.manalejandro.motivame.data.Task
import com.manalejandro.motivame.data.TaskRepository
import com.manalejandro.motivame.widget.MotivameWidget
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -65,6 +66,7 @@ class TaskViewModel(application: Application) : AndroidViewModel(application) {
viewModelScope.launch {
repository.addTask(task)
onRescheduleReminders?.invoke(_notificationEnabled.value)
MotivameWidget.requestUpdate(getApplication())
}
}
@@ -72,6 +74,7 @@ class TaskViewModel(application: Application) : AndroidViewModel(application) {
viewModelScope.launch {
repository.updateTask(task)
onRescheduleReminders?.invoke(_notificationEnabled.value)
MotivameWidget.requestUpdate(getApplication())
}
}
@@ -79,6 +82,7 @@ class TaskViewModel(application: Application) : AndroidViewModel(application) {
viewModelScope.launch {
repository.deleteTask(taskId)
onRescheduleReminders?.invoke(_notificationEnabled.value)
MotivameWidget.requestUpdate(getApplication())
}
}

Ver fichero

@@ -0,0 +1,198 @@
package com.manalejandro.motivame.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.RemoteViews
import com.manalejandro.motivame.MainActivity
import com.manalejandro.motivame.R
import com.manalejandro.motivame.data.Task
import com.manalejandro.motivame.data.TaskRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
class MotivameWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { updateWidget(context, appWidgetManager, it) }
}
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
newOptions: Bundle
) {
updateWidget(context, appWidgetManager, appWidgetId)
}
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
if (intent.action == ACTION_REFRESH) {
val mgr = AppWidgetManager.getInstance(context)
mgr.getAppWidgetIds(ComponentName(context, MotivameWidget::class.java))
.forEach { updateWidget(context, mgr, it) }
}
}
companion object {
const val ACTION_REFRESH = "com.manalejandro.motivame.WIDGET_REFRESH"
// ── Número de tareas según altura real (MIN_HEIGHT) ─────────────
// ~1 fila ≈ 74dp, ~2 filas ≈ 148dp, ~3 filas ≈ 222dp, ~4 filas ≈ 296dp
private fun taskCount(heightDp: Int) = when {
heightDp >= 220 -> 3
heightDp >= 145 -> 2
else -> 1
}
// ── Número de metas por tarea según espacio disponible ───────────
// Se divide la altura disponible entre el número de tareas para estimar
// el espacio por tarea y decidir cuántas metas caben.
private fun goalsPerTask(heightDp: Int, tasks: Int): Int {
val spacePerTask = heightDp / tasks
return when {
spacePerTask >= 160 -> 3 // mucho espacio → 3 metas
spacePerTask >= 100 -> 2 // espacio medio → 2 metas
else -> 1 // poco espacio → 1 meta
}
}
private fun layoutFor(tasks: Int) = when (tasks) {
3 -> R.layout.widget_motivame_large
2 -> R.layout.widget_motivame_medium
else -> R.layout.widget_motivame_small
}
// IDs agrupados por tarea y slot de meta
private val TITLE_IDS = intArrayOf(
R.id.widget_task_title, R.id.widget_task2_title, R.id.widget_task3_title
)
private val GOAL_IDS = arrayOf(
intArrayOf(R.id.widget_t1_goal1, R.id.widget_t1_goal2, R.id.widget_t1_goal3),
intArrayOf(R.id.widget_t2_goal1, R.id.widget_t2_goal2, R.id.widget_t2_goal3),
intArrayOf(R.id.widget_t3_goal1, R.id.widget_t3_goal2, R.id.widget_t3_goal3)
)
private val CHIP_IDS = intArrayOf(
R.id.widget_chip1, R.id.widget_chip2, R.id.widget_chip3
)
fun updateWidget(context: Context, mgr: AppWidgetManager, widgetId: Int) {
CoroutineScope(Dispatchers.IO).launch {
val options = mgr.getAppWidgetOptions(widgetId)
// MIN_HEIGHT = altura real actual del widget en el launcher
val heightDp = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, 110)
val numTasks = taskCount(heightDp)
val numGoals = goalsPerTask(heightDp, numTasks)
val showChip = numTasks == 3 // chip solo en layout grande
val activeTasks = TaskRepository(context).tasks.first().filter { it.isActive }
val views = RemoteViews(context.packageName, layoutFor(numTasks))
// Click → abrir app
views.setOnClickPendingIntent(
R.id.widget_root,
PendingIntent.getActivity(
context, widgetId,
Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
},
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
)
views.setTextViewText(R.id.widget_hint,
context.getString(R.string.widget_tap_to_open))
if (activeTasks.isEmpty()) {
views.setTextViewText(R.id.widget_status, "")
views.setTextViewText(R.id.widget_task_title, "Motívame")
views.setTextViewText(R.id.widget_t1_goal1,
context.getString(R.string.widget_no_tasks))
// ocultar metas 2 y 3 del slot 1
views.setViewVisibility(R.id.widget_t1_goal2, View.GONE)
views.setViewVisibility(R.id.widget_t1_goal3, View.GONE)
// ocultar slots extra
if (numTasks >= 2) hideTaskSlot(views, 1, showChip)
if (numTasks >= 3) hideTaskSlot(views, 2, showChip)
} else {
views.setTextViewText(R.id.widget_status, "")
for (slot in 0 until numTasks) {
val task = activeTasks.getOrNull(slot)
fillTaskSlot(context, views, slot, task, numGoals, showChip)
}
}
mgr.updateAppWidget(widgetId, views)
}
}
private fun fillTaskSlot(
context: Context,
views: RemoteViews,
slot: Int, // 0-based
task: Task?,
numGoals: Int,
showChip: Boolean
) {
val titleId = TITLE_IDS[slot]
val goalIds = GOAL_IDS[slot]
if (task == null) {
hideTaskSlot(views, slot, showChip)
return
}
views.setViewVisibility(titleId, View.VISIBLE)
views.setTextViewText(titleId, task.title)
// Rellenar metas con opacidad decreciente; ocultar las que excedan numGoals
val goals = task.goals
for (i in 0..2) {
val goalId = goalIds[i]
if (i < numGoals && i < goals.size) {
views.setViewVisibility(goalId, View.VISIBLE)
views.setTextViewText(goalId, "🎯 ${goals[i]}")
} else {
views.setViewVisibility(goalId, View.GONE)
}
}
// Chip de avisos (solo layout grande)
if (showChip) {
val chipId = CHIP_IDS[slot]
val chipText = if (task.repeatEveryDays == 1)
context.getString(R.string.task_summary_reminders_daily, task.dailyReminders)
else
context.getString(R.string.task_summary_reminders, task.dailyReminders, task.repeatEveryDays)
views.setViewVisibility(chipId, View.VISIBLE)
views.setTextViewText(chipId, "🔔 $chipText")
}
}
private fun hideTaskSlot(views: RemoteViews, slot: Int, showChip: Boolean) {
views.setViewVisibility(TITLE_IDS[slot], View.GONE)
GOAL_IDS[slot].forEach { views.setViewVisibility(it, View.GONE) }
if (showChip) views.setViewVisibility(CHIP_IDS[slot], View.GONE)
}
fun requestUpdate(context: Context) {
context.sendBroadcast(
Intent(context, MotivameWidget::class.java).apply {
action = ACTION_REFRESH
}
)
}
}
}

Ver fichero

@@ -5,6 +5,7 @@ import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.manalejandro.motivame.data.TaskRepository
import com.manalejandro.motivame.notifications.NotificationHelper
import com.manalejandro.motivame.widget.MotivameWidget
import kotlinx.coroutines.flow.first
class DailyReminderWorker(
@@ -38,6 +39,9 @@ class DailyReminderWorker(
notificationHelper.sendTaskReminder(it, soundEnabled)
}
// Refrescar el widget con la meta actualizada
MotivameWidget.requestUpdate(applicationContext)
return Result.success()
}
}

Ver fichero

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#6366F1"
android:endColor="#8B5CF6"
android:angle="135"
android:type="linear" />
<corners android:radius="16dp" />
</shape>

Ver fichero

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#26FFFFFF" />
<corners android:radius="10dp" />
</shape>

Ver fichero

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/widget_background"
android:padding="16dp"
android:clickable="true">
<!-- Cabecera: icono + nombre de la app -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="⭐ Motívame"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold"
android:alpha="0.8" />
<TextView
android:id="@+id/widget_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="●"
android:textColor="#10B981"
android:textSize="10sp" />
</LinearLayout>
<!-- Título de la tarea -->
<TextView
android:id="@+id/widget_task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Tarea"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="6dp" />
<!-- Meta aleatoria -->
<TextView
android:id="@+id/widget_goal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="🎯 Meta"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:alpha="0.85"
android:maxLines="2"
android:ellipsize="end" />
<!-- Pie: toca para abrir -->
<TextView
android:id="@+id/widget_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Toca para abrir →"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.55"
android:gravity="end"
android:layout_marginTop="4dp" />
</LinearLayout>

Ver fichero

@@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout GRANDE: 3 tareas · 3 metas por tarea + chip de avisos -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/widget_background"
android:padding="14dp"
android:clickable="true">
<!-- Cabecera -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="⭐ Motívame"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold"
android:alpha="0.8" />
<TextView
android:id="@+id/widget_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="●"
android:textColor="#10B981"
android:textSize="10sp" />
</LinearLayout>
<!-- Tarea 1 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp"
android:layout_marginBottom="5dp">
<TextView
android:id="@+id/widget_task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="3dp" />
<TextView
android:id="@+id/widget_t1_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/widget_t1_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_t1_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_chip1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.6"
android:layout_marginTop="3dp"
android:visibility="gone" />
</LinearLayout>
<!-- Tarea 2 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp"
android:layout_marginBottom="5dp">
<TextView
android:id="@+id/widget_task2_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="3dp" />
<TextView
android:id="@+id/widget_t2_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/widget_t2_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_t2_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_chip2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.6"
android:layout_marginTop="3dp"
android:visibility="gone" />
</LinearLayout>
<!-- Tarea 3 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp"
android:layout_marginBottom="4dp">
<TextView
android:id="@+id/widget_task3_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="3dp" />
<TextView
android:id="@+id/widget_t3_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/widget_t3_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_t3_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_chip3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.6"
android:layout_marginTop="3dp"
android:visibility="gone" />
</LinearLayout>
<!-- Pie -->
<TextView
android:id="@+id/widget_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.5"
android:gravity="end" />
</LinearLayout>

Ver fichero

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout MEDIANO: 2 tareas · 2 metas por tarea -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/widget_background"
android:padding="14dp"
android:clickable="true">
<!-- Cabecera -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="⭐ Motívame"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:textStyle="bold"
android:alpha="0.8" />
<TextView
android:id="@+id/widget_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="●"
android:textColor="#10B981"
android:textSize="10sp" />
</LinearLayout>
<!-- Tarea 1 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp"
android:layout_marginBottom="6dp">
<TextView
android:id="@+id/widget_task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="3dp" />
<TextView
android:id="@+id/widget_t1_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/widget_t1_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_t1_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
</LinearLayout>
<!-- Tarea 2 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp"
android:layout_marginBottom="4dp">
<TextView
android:id="@+id/widget_task2_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="13sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="3dp" />
<TextView
android:id="@+id/widget_t2_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/widget_t2_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
<TextView
android:id="@+id/widget_t2_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp"
android:visibility="gone" />
</LinearLayout>
<!-- Pie -->
<TextView
android:id="@+id/widget_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.5"
android:gravity="end" />
</LinearLayout>

Ver fichero

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout PEQUEÑO: 1 tarea · 1 meta visible -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/widget_background"
android:padding="12dp"
android:clickable="true">
<!-- Cabecera -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="6dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="⭐ Motívame"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:textStyle="bold"
android:alpha="0.8" />
<TextView
android:id="@+id/widget_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="●"
android:textColor="#10B981"
android:textSize="10sp" />
</LinearLayout>
<!-- Tarea 1 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="@drawable/widget_task_bg"
android:padding="8dp">
<TextView
android:id="@+id/widget_task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="14sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="4dp" />
<!-- Meta 1 (siempre visible) -->
<TextView
android:id="@+id/widget_t1_goal1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:alpha="0.85"
android:maxLines="1"
android:ellipsize="end" />
<!-- Meta 2 (oculta en small) -->
<TextView
android:id="@+id/widget_t1_goal2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:alpha="0.75"
android:maxLines="1"
android:ellipsize="end"
android:visibility="gone" />
<!-- Meta 3 (oculta en small) -->
<TextView
android:id="@+id/widget_t1_goal3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:alpha="0.65"
android:maxLines="1"
android:ellipsize="end"
android:visibility="gone" />
</LinearLayout>
<!-- Pie -->
<TextView
android:id="@+id/widget_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:alpha="0.5"
android:gravity="end"
android:layout_marginTop="4dp" />
</LinearLayout>

Ver fichero

@@ -76,5 +76,11 @@
<string name="notification_default_message">Denke daran, diese Aufgabe abzuschließen!</string>
<string name="notification_big_text">📝 Aufgabe: %1$s\n\n🎯 Denk daran: %2$s</string>
<!-- Widget -->
<string name="widget_description">Zeigt deine aktive Aufgabe und ein motivierendes Ziel</string>
<string name="widget_no_tasks">Keine aktiven Aufgaben.\nÖffne Motivier mich, um eine hinzuzufügen.</string>
<string name="widget_tap_to_open">Tippen zum Öffnen →</string>
<string name="widget_active">aktiv</string>
</resources>

Ver fichero

@@ -81,6 +81,12 @@
<!-- Notifications -->
<string name="notification_default_message">Remember to complete this task!</string>
<string name="notification_big_text">📝 Task: %1$s\n\n🎯 Remember: %2$s</string>
<!-- Widget -->
<string name="widget_description">Shows your active task and a motivational goal</string>
<string name="widget_no_tasks">No active tasks.\nOpen Motivate Me to add one.</string>
<string name="widget_tap_to_open">Tap to open →</string>
<string name="widget_active">active</string>
</resources>

Ver fichero

@@ -76,5 +76,11 @@
<string name="notification_default_message">N\'oubliez pas de terminer cette tâche !</string>
<string name="notification_big_text">📝 Tâche : %1$s\n\n🎯 Rappel : %2$s</string>
<!-- Widget -->
<string name="widget_description">Affiche votre tâche active et un objectif motivationnel</string>
<string name="widget_no_tasks">Aucune tâche active.\nOuvrez Motivez-moi pour en ajouter une.</string>
<string name="widget_tap_to_open">Toucher pour ouvrir →</string>
<string name="widget_active">active</string>
</resources>

Ver fichero

@@ -76,5 +76,11 @@
<string name="notification_default_message">このタスクを完了することを忘れずに!</string>
<string name="notification_big_text">📝 タスク:%1$s\n\n🎯 リマインダー:%2$s</string>
<!-- Widget -->
<string name="widget_description">アクティブなタスクとモチベーション目標を表示</string>
<string name="widget_no_tasks">アクティブなタスクがありません。\nやる気アップを開いて追加してください。</string>
<string name="widget_tap_to_open">タップして開く →</string>
<string name="widget_active">アクティブ</string>
</resources>

Ver fichero

@@ -76,5 +76,11 @@
<string name="notification_default_message">이 작업을 완료하는 것을 잊지 마세요!</string>
<string name="notification_big_text">📝 작업: %1$s\n\n🎯 알림: %2$s</string>
<!-- Widget -->
<string name="widget_description">활성 작업과 동기 부여 목표를 표시합니다</string>
<string name="widget_no_tasks">활성 작업이 없습니다.\n동기부여 앱을 열어 추가하세요.</string>
<string name="widget_tap_to_open">탭하여 열기 →</string>
<string name="widget_active">활성</string>
</resources>

Ver fichero

@@ -76,5 +76,11 @@
<string name="notification_default_message">Lembre-se de completar esta tarefa!</string>
<string name="notification_big_text">📝 Tarefa: %1$s\n\n🎯 Lembre-se: %2$s</string>
<!-- Widget -->
<string name="widget_description">Mostra sua tarefa ativa e uma meta motivacional</string>
<string name="widget_no_tasks">Sem tarefas ativas.\nAbra Motiva-me para adicionar uma.</string>
<string name="widget_tap_to_open">Toque para abrir →</string>
<string name="widget_active">ativa</string>
</resources>

Ver fichero

@@ -79,8 +79,11 @@
<string name="language_restart_hint">应用将重启以应用语言更改</string>
<!-- Notifications -->
<string name="notification_default_message">记得完成这个任务!</string>
<string name="notification_big_text">📝 任务:%1$s\n\n🎯 提醒:%2$s</string>
<!-- Widget -->
<string name="widget_description">显示您的活跃任务和激励目标</string>
<string name="widget_no_tasks">没有活跃任务。\n打开激励我来添加一个。</string>
<string name="widget_tap_to_open">点击打开 →</string>
<string name="widget_active">活跃</string>
</resources>

Ver fichero

@@ -80,4 +80,10 @@
<!-- Notifications -->
<string name="notification_default_message">¡Recuerda completar esta tarea!</string>
<string name="notification_big_text">📝 Tarea: %1$s\n\n🎯 Recuerda: %2$s</string>
<!-- Widget -->
<string name="widget_description">Muestra tu tarea activa y una meta motivacional</string>
<string name="widget_no_tasks">Sin tareas activas.\nAbre Motívame para añadir una.</string>
<string name="widget_tap_to_open">Toca para abrir →</string>
<string name="widget_active">activa</string>
</resources>

Ver fichero

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="110dp"
android:targetCellWidth="3"
android:targetCellHeight="2"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/widget_motivame"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:description="@string/widget_description"
android:previewLayout="@layout/widget_motivame" />