add widget
Algunas comprobaciones han fallado
Build & Publish APK Release / build (push) Failing after 6m8s
Algunas comprobaciones han fallado
Build & Publish APK Release / build (push) Failing after 6m8s
Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
198
app/src/main/java/com/manalejandro/motivame/widget/MotivameWidget.kt
Archivo normal
198
app/src/main/java/com/manalejandro/motivame/widget/MotivameWidget.kt
Archivo normal
@@ -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
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
11
app/src/main/res/drawable/widget_background.xml
Archivo normal
11
app/src/main/res/drawable/widget_background.xml
Archivo normal
@@ -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>
|
||||
|
||||
7
app/src/main/res/drawable/widget_task_bg.xml
Archivo normal
7
app/src/main/res/drawable/widget_task_bg.xml
Archivo normal
@@ -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>
|
||||
|
||||
78
app/src/main/res/layout/widget_motivame.xml
Archivo normal
78
app/src/main/res/layout/widget_motivame.xml
Archivo normal
@@ -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>
|
||||
|
||||
248
app/src/main/res/layout/widget_motivame_large.xml
Archivo normal
248
app/src/main/res/layout/widget_motivame_large.xml
Archivo normal
@@ -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>
|
||||
|
||||
162
app/src/main/res/layout/widget_motivame_medium.xml
Archivo normal
162
app/src/main/res/layout/widget_motivame_medium.xml
Archivo normal
@@ -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>
|
||||
|
||||
106
app/src/main/res/layout/widget_motivame_small.xml
Archivo normal
106
app/src/main/res/layout/widget_motivame_small.xml
Archivo normal
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
13
app/src/main/res/xml/motivame_widget_info.xml
Archivo normal
13
app/src/main/res/xml/motivame_widget_info.xml
Archivo normal
@@ -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" />
|
||||
|
||||
Referencia en una nueva incidencia
Block a user