diff --git a/android-base/build.gradle b/android-base/build.gradle
index 128998dd4..11075bb4f 100644
--- a/android-base/build.gradle
+++ b/android-base/build.gradle
@@ -24,6 +24,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
+ buildToolsVersion '26.0.2'
}
dependencies {
diff --git a/android-pickers/build.gradle b/android-pickers/build.gradle
index fc75627d8..c644c66ad 100644
--- a/android-pickers/build.gradle
+++ b/android-pickers/build.gradle
@@ -18,6 +18,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ buildToolsVersion '26.0.2'
}
dependencies {
diff --git a/build.gradle b/build.gradle
index b21b92ae7..6692adb1e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.0.0-beta6'
+ classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
diff --git a/uhabits-android/build.gradle b/uhabits-android/build.gradle
index 5acaf1c1d..8e2281cfb 100644
--- a/uhabits-android/build.gradle
+++ b/uhabits-android/build.gradle
@@ -89,6 +89,7 @@ android {
sourceSets {
main.assets.srcDirs += '../uhabits-core/src/main/resources/'
}
+ buildToolsVersion '26.0.2'
}
dependencies {
diff --git a/uhabits-android/src/main/AndroidManifest.xml b/uhabits-android/src/main/AndroidManifest.xml
index 1998c938c..ec52f93f1 100644
--- a/uhabits-android/src/main/AndroidManifest.xml
+++ b/uhabits-android/src/main/AndroidManifest.xml
@@ -84,13 +84,6 @@
-
-
-
-
-
@@ -110,7 +103,7 @@
android:name="android.appwidget.provider"
android:resource="@xml/widget_checkmark_info"/>
-
{
- val app = context.getApplicationContext() as HabitsApplication
- val widgetPrefs = app.component.widgetPreferences
- val habitIds = widgetPrefs.getHabitIdsGroupFromWidgetId(widgetId)
- return habitIds
- }
-}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidgetProvider.kt
index d972fd552..1dc6c6a10 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidgetProvider.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidgetProvider.kt
@@ -18,24 +18,17 @@
*/
package org.isoron.uhabits.widgets
-import android.content.*
-import org.isoron.uhabits.HabitsApplication
+import android.content.Context
class CheckmarkWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
- try {
- val habit = getHabitFromWidgetId(id)
+ // if the habit was null, but did not have a habit id associated with a stack widget,
+ // `getHabitFromWidgetId` will throw a HabitNotFoundException
+ val habit = getHabitFromWidgetId(id)
+ if (habit != null) {
return CheckmarkWidget(context, id, habit)
- } catch (e: Exception) {
- val habitIds = getHabitIdsGroupFromWidget(context, id)
- return CheckmarkStackWidget(context, id, habitIds)
+ } else {
+ return StackWidget(context, id, StackWidgetType.CHECKMARK)
}
}
-
- private fun getHabitIdsGroupFromWidget(context: Context, widgetId: Int) : List {
- val app = context.getApplicationContext() as HabitsApplication
- val widgetPrefs = app.component.widgetPreferences
- val habitIds = widgetPrefs.getHabitIdsGroupFromWidgetId(widgetId)
- return habitIds
- }
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt
index f35320b41..b21906469 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt
@@ -19,11 +19,17 @@
package org.isoron.uhabits.widgets
-import android.content.*
+import android.content.Context
class FrequencyWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
+ // if the habit was null, but did not have a habit id associated with a stack widget,
+ // `getHabitFromWidgetId` will throw a HabitNotFoundException
val habit = getHabitFromWidgetId(id)
- return FrequencyWidget(context, id, habit)
+ if (habit != null) {
+ return FrequencyWidget(context, id, habit)
+ } else {
+ return StackWidget(context, id, StackWidgetType.FREQUENCY)
+ }
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitGroupPickerDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitGroupPickerDialog.kt
deleted file mode 100644
index d94436236..000000000
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitGroupPickerDialog.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2016 Álinson Santos Xavier
- *
- * This file is part of Loop Habit Tracker.
- *
- * Loop Habit Tracker is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * Loop Habit Tracker is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see .
- */
-
-package org.isoron.uhabits.widgets
-
-import android.app.Activity
-import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
-import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.*
-import android.widget.CompoundButton
-import org.isoron.uhabits.HabitsApplication
-import org.isoron.uhabits.R
-import org.isoron.uhabits.core.models.HabitList
-import org.isoron.uhabits.core.preferences.WidgetPreferences
-
-class HabitGroupPickerDialog : Activity(), AdapterView.OnItemClickListener {
-
- private var widgetId = 0
- private lateinit var habitList: HabitList
- private lateinit var preferences: WidgetPreferences
- private lateinit var habitIds: ArrayList
- private lateinit var widgetUpdater: WidgetUpdater
- private lateinit var habitIdsSelected: ArrayList
- private lateinit var habitListView: ListView
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val component = (applicationContext as HabitsApplication).component
- habitList = component.habitList
- preferences = component.widgetPreferences
- widgetUpdater = component.widgetUpdater
- widgetId = intent.extras?.getInt(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID) ?: 0
- habitIdsSelected = ArrayList()
-
- habitIds = ArrayList()
- val habitNames = ArrayList()
- for (h in habitList) {
- if (h.isArchived) continue
- habitIds.add(h.getId()!!)
- habitNames.add(h.name)
- }
-
- setContentView(R.layout.stack_widget_configure_activity)
- habitListView = findViewById(R.id.stackWidgetListView) as ListView
- with(habitListView) {
- adapter = ListAdapter(context, R.layout.habit_checkbox_list_item,
- R.id.listItemHabitName, R.id.listItemHabitCheckbox, habitNames)
- onItemClickListener = this@HabitGroupPickerDialog
- }
- with(findViewById(R.id.doneConfigureButton) as Button) {
- setOnClickListener {
- if (habitIdsSelected.size == 1) {
- preferences.addWidget(widgetId, habitIdsSelected.first())
- widgetUpdater.updateWidgets()
- setResult(Activity.RESULT_OK, Intent().apply {
- putExtra(EXTRA_APPWIDGET_ID, widgetId)
- })
- finish()
- } else if (!habitIdsSelected.isEmpty()) {
- preferences.addWidget(widgetId, habitIdsSelected.toString())
- widgetUpdater.updateWidgets()
- setResult(Activity.RESULT_OK, Intent().apply {
- putExtra(EXTRA_APPWIDGET_ID, widgetId)
- })
- finish()
- } else {
- Toast.makeText(context, getString(R.string.select_habit_requirement_prompt),
- Toast.LENGTH_SHORT).show()
- }
- }
- }
- }
-
- override fun onItemClick(parent: AdapterView<*>,
- view: View,
- position: Int,
- id: Long) {
- val checkbox = view.findViewById(R.id.listItemHabitCheckbox) as CheckBox
- checkbox.isChecked = !checkbox.isChecked
- }
-
- private inner class ListAdapter(context: Context,
- private var layoutResource: Int,
- private var textViewResourceId: Int,
- private var checkBoxResourceId: Int,
- private var habitNames: List) :
- ArrayAdapter(context, layoutResource, textViewResourceId, habitNames) {
-
- override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
- val layoutInflater: LayoutInflater = LayoutInflater.from(context)
- val view = layoutInflater.inflate(layoutResource, null)
-
- val item = getItem(position)
- if (item != null) {
- val tv = view.findViewById(textViewResourceId) as TextView
- tv.text = habitNames.get(position)
- val cb = view.findViewById(checkBoxResourceId) as CheckBox
- cb.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
- if (isChecked) {
- habitIdsSelected.add(habitIds.get(position))
- } else {
- habitIdsSelected.remove(habitIds.get(position))
- }
- })
- }
-
- return view
- }
-
- }
-}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitPickerDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitPickerDialog.kt
index c1e8f8d9f..724b85d5c 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitPickerDialog.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitPickerDialog.kt
@@ -23,6 +23,7 @@ import android.app.*
import android.appwidget.AppWidgetManager.*
import android.content.*
import android.os.*
+import android.util.Log
import android.view.*
import android.widget.*
import org.isoron.uhabits.*
@@ -61,6 +62,16 @@ class HabitPickerDialog : Activity(), AdapterView.OnItemClickListener {
habitNames)
onItemClickListener = this@HabitPickerDialog
}
+ with(findViewById(R.id.createStackWidgetButton) as Button) {
+ setOnClickListener(View.OnClickListener {
+ preferences.addWidget(widgetId, WidgetPreferences.STACK_WIDGET_HABITS)
+ widgetUpdater.updateWidgets()
+ setResult(Activity.RESULT_OK, Intent().apply {
+ putExtra(EXTRA_APPWIDGET_ID, widgetId)
+ })
+ finish()
+ })
+ }
}
override fun onItemClick(parent: AdapterView<*>,
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt
index f7b5eb482..3ba9f4dd2 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt
@@ -18,11 +18,17 @@
*/
package org.isoron.uhabits.widgets
-import android.content.*
+import android.content.Context
class HistoryWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
+ // if the habit was null, but did not have a habit id associated with a stack widget,
+ // `getHabitFromWidgetId` will throw a HabitNotFoundException
val habit = getHabitFromWidgetId(id)
- return HistoryWidget(context, id, habit)
+ if (habit != null) {
+ return HistoryWidget(context, id, habit)
+ } else {
+ return StackWidget(context, id, StackWidgetType.HISTORY)
+ }
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.kt
index fa31a63ac..63644b0b9 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.kt
@@ -18,13 +18,19 @@
*/
package org.isoron.uhabits.widgets
-import android.content.*
-import org.isoron.uhabits.*
+import android.content.Context
+import org.isoron.uhabits.HabitsApplication
class ScoreWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
- val component = (context.applicationContext as HabitsApplication).component
+ // if the habit was null, but did not have a habit id associated with a stack widget,
+ // `getHabitFromWidgetId` will throw a HabitNotFoundException
val habit = getHabitFromWidgetId(id)
- return ScoreWidget(context, id, habit, component.preferences)
+ val component = (context.applicationContext as HabitsApplication).component
+ if (habit != null) {
+ return ScoreWidget(context, id, habit, component.preferences)
+ } else {
+ return StackWidget(context, id, StackWidgetType.SCORE)
+ }
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidget.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt
similarity index 67%
rename from uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidget.kt
rename to uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt
index 1f494b201..3a0aede4c 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidget.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt
@@ -22,14 +22,14 @@ package org.isoron.uhabits.widgets
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
+import android.net.Uri
import android.view.View
import android.widget.RemoteViews
-import org.isoron.uhabits.R
-class CheckmarkStackWidget(
+class StackWidget(
context: Context,
widgetId: Int,
- private val habitIds: List
+ private val widgetType: StackWidgetType
) : BaseWidget(context, widgetId) {
override fun getOnClickPendingIntent(context: Context) = null
@@ -39,14 +39,16 @@ class CheckmarkStackWidget(
}
override fun getRemoteViews(width: Int, height: Int): RemoteViews {
- val remoteViews = RemoteViews(context.packageName, R.layout.stackview_widget)
- val serviceIntent = Intent(context, CheckmarkStackWidgetService::class.java)
+ val remoteViews = RemoteViews(context.packageName, StackWidgetType.getStackWidgetLayoutId(widgetType))
+ val serviceIntent = Intent(context, StackWidgetService::class.java)
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
- serviceIntent.putExtra(CheckmarkStackWidgetService.HABIT_IDS_SELECTED, habitIds.toLongArray())
- remoteViews.setRemoteAdapter(R.id.stackWidgetView, serviceIntent)
- AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(id, R.id.stackWidgetView)
+ serviceIntent.putExtra(StackWidgetService.WIDGET_TYPE, widgetType.value)
+ serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)))
+ remoteViews.setRemoteAdapter(StackWidgetType.getStackWidgetAdapterViewId(widgetType), serviceIntent)
+ AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(id, StackWidgetType.getStackWidgetAdapterViewId(widgetType))
// TODO what should the empty view look like?
- remoteViews.setEmptyView(R.id.stackWidgetView, R.id.stackWidgetEmptyView)
+ remoteViews.setEmptyView(StackWidgetType.getStackWidgetAdapterViewId(widgetType),
+ StackWidgetType.getStackWidgetEmptyViewId(widgetType))
return remoteViews
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidgetService.java b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java
similarity index 52%
rename from uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidgetService.java
rename to uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java
index 09f8a92e6..e8fb06f53 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidgetService.java
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java
@@ -4,6 +4,8 @@ import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.support.annotation.NonNull;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
@@ -12,37 +14,36 @@ import org.isoron.uhabits.HabitsApplication;
import org.isoron.uhabits.core.models.Habit;
import java.util.ArrayList;
-import java.util.List;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
import static org.isoron.androidbase.utils.InterfaceUtils.dpToPixels;
-import static org.isoron.uhabits.widgets.CheckmarkStackWidgetService.HABIT_IDS_SELECTED;
+import static org.isoron.uhabits.widgets.StackWidgetService.WIDGET_TYPE;
-public class CheckmarkStackWidgetService extends RemoteViewsService {
+public class StackWidgetService extends RemoteViewsService {
- public static final String HABIT_IDS_SELECTED = "HABIT_IDS_SELECTED";
+ public static final String WIDGET_TYPE = "WIDGET_TYPE";
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
- return new CheckmarkStackRemoteViewsFactory(this.getApplicationContext(), intent);
+ return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
}
}
-class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
+class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private int mAppWidgetId;
private ArrayList mHabitList;
- private List mHabitsSelected;
+ private StackWidgetType mWidgetType;
- public CheckmarkStackRemoteViewsFactory(Context context, Intent intent) {
+ public StackRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
- mHabitsSelected = new ArrayList<>();
- for (long id : intent.getLongArrayExtra(HABIT_IDS_SELECTED)) {
- mHabitsSelected.add(id);
+ int widgetTypeValue = intent.getIntExtra(WIDGET_TYPE, -1);
+ if (widgetTypeValue != -1) {
+ mWidgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue);
}
}
@@ -51,7 +52,7 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
}
public void onDestroy() {
- mHabitList.clear();
+
}
public int getCount() {
@@ -75,20 +76,62 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
public RemoteViews getViewAt(int position) {
RemoteViews rv = null;
-
if (position < getCount()) {
Habit habit = mHabitList.get(position);
- CheckmarkWidget checkmarkWidget = new CheckmarkWidget(mContext, mAppWidgetId, habit);
+ BaseWidget widget = initializeWidget(habit);
Bundle options = AppWidgetManager.getInstance(mContext).getAppWidgetOptions(mAppWidgetId);
- checkmarkWidget.setDimensions(getDimensionsFromOptions(mContext, options));
- RemoteViews landscape = checkmarkWidget.getLandscapeRemoteViews();
- RemoteViews portrait = checkmarkWidget.getPortraitRemoteViews();
- rv = new RemoteViews(landscape, portrait);
+ widget.setDimensions(getDimensionsFromOptions(mContext, options));
+ final RemoteViews[] landscape = new RemoteViews[1];
+ final RemoteViews[] portrait = new RemoteViews[1];
+
+ Object lock = new Object();
+ final boolean[] flag = {false};
+
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (lock) {
+ landscape[0] = widget.getLandscapeRemoteViews();
+ portrait[0] = widget.getPortraitRemoteViews();
+ flag[0] = true;
+ lock.notifyAll();
+ }
+ }
+ });
+
+ synchronized (lock) {
+ while (!flag[0]) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+
+ }
+ }
+ }
+
+ rv = new RemoteViews(landscape[0], portrait[0]);
}
return rv;
}
+ private BaseWidget initializeWidget(Habit habit) {
+ switch (mWidgetType) {
+ case CHECKMARK:
+ return new CheckmarkWidget(mContext, mAppWidgetId, habit);
+ case FREQUENCY:
+ return new FrequencyWidget(mContext, mAppWidgetId, habit);
+ case SCORE:
+ HabitsApplication app = (HabitsApplication) mContext.getApplicationContext();
+ return new ScoreWidget(mContext, mAppWidgetId, habit, app.getComponent().getPreferences());
+ case HISTORY:
+ return new HistoryWidget(mContext, mAppWidgetId, habit);
+ case STREAKS:
+ return new StreakWidget(mContext, mAppWidgetId, habit);
+ }
+ return null;
+ }
+
public RemoteViews getLoadingView() {
return null;
}
@@ -109,9 +152,7 @@ class CheckmarkStackRemoteViewsFactory implements RemoteViewsService.RemoteViews
mHabitList = new ArrayList<>();
HabitsApplication app = (HabitsApplication) mContext.getApplicationContext();
for (Habit h : app.getComponent().getHabitList()) {
- if (mHabitsSelected.contains(h.getId())) {
- mHabitList.add(h);
- }
+ mHabitList.add(h);
}
}
}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java
new file mode 100644
index 000000000..a5aeebb82
--- /dev/null
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java
@@ -0,0 +1,89 @@
+package org.isoron.uhabits.widgets;
+
+import org.isoron.uhabits.R;
+
+/**
+ * Created by victoryu on 11/3/17.
+ */
+
+public enum StackWidgetType {
+
+ CHECKMARK(0),
+ FREQUENCY(1),
+ SCORE(2), // habit strength widget
+ HISTORY(3),
+ STREAKS(4);
+
+ private int value;
+ StackWidgetType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static StackWidgetType getWidgetTypeFromValue(int value) {
+ if (CHECKMARK.getValue() == value) {
+ return CHECKMARK;
+ } else if (FREQUENCY.getValue() == value) {
+ return FREQUENCY;
+ } else if (SCORE.getValue() == value) {
+ return SCORE;
+ } else if (HISTORY.getValue() == value) {
+ return HISTORY;
+ } else if (STREAKS.getValue() == value) {
+ return STREAKS;
+ }
+ return null;
+ }
+
+ public static int getStackWidgetLayoutId(StackWidgetType type) {
+ switch (type) {
+ case CHECKMARK:
+ return R.layout.checkmark_stackview_widget;
+ case FREQUENCY:
+ return R.layout.frequency_stackview_widget;
+ case SCORE:
+ return R.layout.score_stackview_widget;
+ case HISTORY:
+ return R.layout.history_stackview_widget;
+ case STREAKS:
+ return R.layout.streak_stackview_widget;
+ }
+ return 0;
+ }
+
+ public static int getStackWidgetAdapterViewId(StackWidgetType type) {
+ switch (type) {
+ case CHECKMARK:
+ return R.id.checkmarkStackWidgetView;
+ case FREQUENCY:
+ return R.id.frequencyStackWidgetView;
+ case SCORE:
+ return R.id.scoreStackWidgetView;
+ case HISTORY:
+ return R.id.historyStackWidgetView;
+ case STREAKS:
+ return R.id.streakStackWidgetView;
+ }
+ return 0;
+ }
+
+ public static int getStackWidgetEmptyViewId(StackWidgetType type) {
+ switch (type) {
+ case CHECKMARK:
+ return R.id.checkmarkStackWidgetEmptyView;
+ case FREQUENCY:
+ return R.id.frequencyStackWidgetEmptyView;
+ case SCORE:
+ return R.id.scoreStackWidgetEmptyView;
+ case HISTORY:
+ return R.id.historyStackWidgetEmptyView;
+ case STREAKS:
+ return R.id.streakStackWidgetEmptyView;
+ }
+ return 0;
+ }
+
+}
diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StreakWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StreakWidgetProvider.kt
index 5284cb9e1..1a2696fff 100644
--- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StreakWidgetProvider.kt
+++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StreakWidgetProvider.kt
@@ -18,11 +18,17 @@
*/
package org.isoron.uhabits.widgets
-import android.content.*
+import android.content.Context
class StreakWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
+ // if the habit was null, but did not have a habit id associated with a stack widget,
+ // `getHabitFromWidgetId` will throw a HabitNotFoundException
val habit = getHabitFromWidgetId(id)
- return StreakWidget(context, id, habit)
+ if (habit != null) {
+ return StreakWidget(context, id, habit)
+ } else {
+ return StackWidget(context, id, StackWidgetType.STREAKS)
+ }
}
}
diff --git a/uhabits-android/src/main/res/layout/stackview_widget.xml b/uhabits-android/src/main/res/layout/checkmark_stackview_widget.xml
similarity index 86%
rename from uhabits-android/src/main/res/layout/stackview_widget.xml
rename to uhabits-android/src/main/res/layout/checkmark_stackview_widget.xml
index 481c23334..14944d743 100644
--- a/uhabits-android/src/main/res/layout/stackview_widget.xml
+++ b/uhabits-android/src/main/res/layout/checkmark_stackview_widget.xml
@@ -3,12 +3,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+
+
+
+
\ No newline at end of file
diff --git a/uhabits-android/src/main/res/layout/history_stackview_widget.xml b/uhabits-android/src/main/res/layout/history_stackview_widget.xml
new file mode 100644
index 000000000..5cd6680ca
--- /dev/null
+++ b/uhabits-android/src/main/res/layout/history_stackview_widget.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/uhabits-android/src/main/res/layout/score_stackview_widget.xml b/uhabits-android/src/main/res/layout/score_stackview_widget.xml
new file mode 100644
index 000000000..3143667c8
--- /dev/null
+++ b/uhabits-android/src/main/res/layout/score_stackview_widget.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/uhabits-android/src/main/res/layout/streak_stackview_widget.xml b/uhabits-android/src/main/res/layout/streak_stackview_widget.xml
new file mode 100644
index 000000000..e867b5b20
--- /dev/null
+++ b/uhabits-android/src/main/res/layout/streak_stackview_widget.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/uhabits-android/src/main/res/layout/widget_configure_activity.xml b/uhabits-android/src/main/res/layout/widget_configure_activity.xml
index 08941ce27..6681ffaf4 100644
--- a/uhabits-android/src/main/res/layout/widget_configure_activity.xml
+++ b/uhabits-android/src/main/res/layout/widget_configure_activity.xml
@@ -1,5 +1,4 @@
-
-
-
+
-
\ No newline at end of file
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uhabits-android/src/main/res/values/strings.xml b/uhabits-android/src/main/res/values/strings.xml
index 1d048de20..df4cc33c5 100644
--- a/uhabits-android/src/main/res/values/strings.xml
+++ b/uhabits-android/src/main/res/values/strings.xml
@@ -125,7 +125,13 @@
Version %s
Frequency
Checkmark
+ StackView Widget For All Habits
Checkmark Stack Widget
+ Frequency Stack Widget
+ Score Stack Widget
+ History Stack Widget
+ Streaks Stack Widget
+
Strength
Best streaks
diff --git a/uhabits-android/src/main/res/xml/widget_checkmark_info.xml b/uhabits-android/src/main/res/xml/widget_checkmark_info.xml
index 39d71f380..4541e5857 100644
--- a/uhabits-android/src/main/res/xml/widget_checkmark_info.xml
+++ b/uhabits-android/src/main/res/xml/widget_checkmark_info.xml
@@ -25,6 +25,6 @@
android:previewImage="@drawable/widget_preview_checkmark"
android:resizeMode="none"
android:updatePeriodMillis="3600000"
- android:configure="org.isoron.uhabits.widgets.HabitGroupPickerDialog"
+ android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
android:widgetCategory="home_screen">
\ No newline at end of file
diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java
index 35e0e09ef..f82e48b58 100644
--- a/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java
+++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java
@@ -21,11 +21,6 @@ package org.isoron.uhabits.core.preferences;
import org.isoron.uhabits.core.AppScope;
import org.isoron.uhabits.core.models.HabitNotFoundException;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
import javax.inject.Inject;
@@ -33,6 +28,9 @@ import javax.inject.Inject;
public class WidgetPreferences {
private Preferences.Storage storage;
+ public static final long STACK_WIDGET_HABITS = -1;
+ public static final long HABIT_NOT_FOUND = -2;
+
@Inject
public WidgetPreferences(Preferences.Storage storage) {
this.storage = storage;
@@ -42,32 +40,13 @@ public class WidgetPreferences {
storage.putLong(getHabitIdKey(widgetId), habitId);
}
- /**
- * @param habitIds the string should be in the format: [habitId1, habitId2, habitId3...]
- */
- public void addWidget(int widgetId, String habitIds) {
- storage.putString(getHabitIdKey(widgetId), habitIds);
- }
-
public long getHabitIdFromWidgetId(int widgetId) {
- Long habitId = storage.getLong(getHabitIdKey(widgetId), -1);
- if (habitId < 0) throw new HabitNotFoundException();
+ Long habitId = storage.getLong(getHabitIdKey(widgetId), HABIT_NOT_FOUND);
+ if (habitId == HABIT_NOT_FOUND) throw new HabitNotFoundException();
return habitId;
}
- public List getHabitIdsGroupFromWidgetId(int widgetId) {
- String habitIdsGroup = storage.getString(getHabitIdKey(widgetId), "");
- if (habitIdsGroup.isEmpty()) throw new HabitNotFoundException();
-
- ArrayList habitIdList = new ArrayList<>();
- for (String s : parseStringToList(habitIdsGroup)) {
- habitIdList.add(Long.parseLong(s.trim()));
- }
-
- return habitIdList;
- }
-
public void removeWidget(int id) {
String habitIdKey = getHabitIdKey(id);
storage.remove(habitIdKey);
@@ -76,9 +55,4 @@ public class WidgetPreferences {
private String getHabitIdKey(int id) {
return String.format("widget-%06d-habit", id);
}
-
- private List parseStringToList(@NotNull String str) {
- return Arrays.asList(str.replace("[", "")
- .replace("]", "").split(","));
- }
}