diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidget.java b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidget.java index bf4ec7844..af99d4a3a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidget.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidget.java @@ -30,22 +30,27 @@ import org.isoron.uhabits.*; import org.isoron.uhabits.core.preferences.*; import org.isoron.uhabits.intents.*; -import static android.view.View.MeasureSpec.*; +import static android.view.View.MeasureSpec.makeMeasureSpec; public abstract class BaseWidget { - private final WidgetPreferences prefs; - private final int id; @NonNull - private WidgetDimensions dimensions; + protected final WidgetPreferences widgetPrefs; @NonNull - private final Context context; + protected final Preferences prefs; + @NonNull protected final PendingIntentFactory pendingIntentFactory; + @NonNull + private final Context context; + + @NonNull + private WidgetDimensions dimensions; + public BaseWidget(@NonNull Context context, int id) { this.id = id; @@ -54,15 +59,16 @@ public abstract class BaseWidget HabitsApplication app = (HabitsApplication) context.getApplicationContext(); - prefs = app.getComponent().getWidgetPreferences(); + widgetPrefs = app.getComponent().getWidgetPreferences(); + prefs = app.getComponent().getPreferences(); pendingIntentFactory = app.getComponent().getPendingIntentFactory(); dimensions = new WidgetDimensions(getDefaultWidth(), getDefaultHeight(), - getDefaultWidth(), getDefaultHeight()); + getDefaultWidth(), getDefaultHeight()); } public void delete() { - prefs.removeWidget(id); + widgetPrefs.removeWidget(id); } @NonNull @@ -80,7 +86,7 @@ public abstract class BaseWidget public RemoteViews getLandscapeRemoteViews() { return getRemoteViews(dimensions.getLandscapeWidth(), - dimensions.getLandscapeHeight()); + dimensions.getLandscapeHeight()); } public abstract PendingIntent getOnClickPendingIntent(Context context); @@ -89,7 +95,7 @@ public abstract class BaseWidget public RemoteViews getPortraitRemoteViews() { return getRemoteViews(dimensions.getPortraitWidth(), - dimensions.getPortraitHeight()); + dimensions.getPortraitHeight()); } public abstract void refreshData(View widgetView); @@ -139,7 +145,7 @@ public abstract class BaseWidget int w = (int) (((float) entireWidth - imageWidth) / 2); int h = (int) (((float) entireHeight - imageHeight) / 2); - return new int[]{ w, h, w, h }; + return new int[]{w, h, w, h}; } @NonNull @@ -183,7 +189,7 @@ public abstract class BaseWidget entireView.measure(specWidth, specHeight); entireView.layout(0, 0, entireView.getMeasuredWidth(), - entireView.getMeasuredHeight()); + entireView.getMeasuredHeight()); View imageView = entireView.findViewById(R.id.imageView); width = imageView.getMeasuredWidth(); diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.java b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.java index b775593ff..41405276a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.java @@ -19,26 +19,19 @@ package org.isoron.uhabits.widgets; -import android.appwidget.AppWidgetManager; -import android.appwidget.AppWidgetProvider; -import android.content.Context; -import android.os.Bundle; -import android.os.Looper; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.widget.RemoteViews; - -import org.isoron.uhabits.HabitsApplication; -import org.isoron.uhabits.R; -import org.isoron.uhabits.core.models.Habit; -import org.isoron.uhabits.core.models.HabitList; -import org.isoron.uhabits.core.models.HabitNotFoundException; -import org.isoron.uhabits.core.preferences.WidgetPreferences; - -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 android.appwidget.*; +import android.content.*; +import android.os.*; +import android.support.annotation.*; +import android.widget.*; + +import org.isoron.uhabits.*; +import org.isoron.uhabits.core.models.*; +import org.isoron.uhabits.core.preferences.*; + +import java.util.*; + +import static android.appwidget.AppWidgetManager.*; import static org.isoron.androidbase.utils.InterfaceUtils.dpToPixels; public abstract class BaseWidgetProvider extends AppWidgetProvider @@ -141,15 +134,18 @@ public abstract class BaseWidgetProvider extends AppWidgetProvider }).start(); } - protected Habit getHabitFromWidgetId(int widgetId) + protected List getHabitsFromWidgetId(int widgetId) { - long habitId = widgetPrefs.getHabitIdFromWidgetId(widgetId); - if (habitId == WidgetPreferences.STACK_WIDGET_HABITS) { - return null; + long selectedIds[] = widgetPrefs.getHabitIdsFromWidgetId(widgetId); + ArrayList selectedHabits = new ArrayList<>(selectedIds.length); + for (long id : selectedIds) + { + Habit h = habits.getById(id); + if (h == null) throw new HabitNotFoundException(); + selectedHabits.add(h); } - Habit habit = habits.getById(habitId); - if (habit == null) throw new HabitNotFoundException(); - return habit; + + return selectedHabits; } @NonNull 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 1dc6c6a10..7d3f64378 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,17 +18,12 @@ */ package org.isoron.uhabits.widgets -import android.content.Context +import android.content.* class CheckmarkWidgetProvider : 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) - if (habit != null) { - return CheckmarkWidget(context, id, habit) - } else { - return StackWidget(context, id, StackWidgetType.CHECKMARK) - } + val habits = getHabitsFromWidgetId(id) + if (habits.size == 1) return CheckmarkWidget(context, id, habits[0]) + else return StackWidget(context, id, StackWidgetType.CHECKMARK, habits) } } 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 b21906469..8c724d17e 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,17 +19,12 @@ package org.isoron.uhabits.widgets -import android.content.Context +import android.content.* 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) - if (habit != null) { - return FrequencyWidget(context, id, habit) - } else { - return StackWidget(context, id, StackWidgetType.FREQUENCY) - } + val habits = getHabitsFromWidgetId(id) + if (habits.size == 1) return FrequencyWidget(context, id, habits[0]) + else return StackWidget(context, id, StackWidgetType.FREQUENCY, habits) } } 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 724b85d5c..3b405b6c3 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,21 +23,21 @@ import android.app.* import android.appwidget.AppWidgetManager.* import android.content.* import android.os.* -import android.util.Log -import android.view.* import android.widget.* +import android.widget.AbsListView.* import org.isoron.uhabits.* import org.isoron.uhabits.core.models.* import org.isoron.uhabits.core.preferences.* import java.util.* -class HabitPickerDialog : Activity(), AdapterView.OnItemClickListener { +class HabitPickerDialog : Activity() { 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 listView: ListView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -45,26 +45,35 @@ class HabitPickerDialog : Activity(), AdapterView.OnItemClickListener { habitList = component.habitList preferences = component.widgetPreferences widgetUpdater = component.widgetUpdater - widgetId = intent.extras?.getInt(EXTRA_APPWIDGET_ID, - INVALID_APPWIDGET_ID) ?: 0 + widgetId = intent.extras?.getInt(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID) ?: 0 - habitIds = ArrayList() + habitIds = ArrayList() val habitNames = ArrayList() for (h in habitList) { if (h.isArchived) continue - habitIds.add(h.getId()!!) + habitIds.add(h.id!!) habitNames.add(h.name) } setContentView(R.layout.widget_configure_activity) - with(findViewById(R.id.listView) as ListView) { - adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, - habitNames) - onItemClickListener = this@HabitPickerDialog + listView = findViewById(R.id.listView) as ListView + + with(listView) { + adapter = ArrayAdapter(context, android.R.layout.simple_list_item_multiple_choice, habitNames) + choiceMode = CHOICE_MODE_MULTIPLE + itemsCanFocus = false } - with(findViewById(R.id.createStackWidgetButton) as Button) { - setOnClickListener(View.OnClickListener { - preferences.addWidget(widgetId, WidgetPreferences.STACK_WIDGET_HABITS) + + with(findViewById(R.id.buttonSave) as Button) { + setOnClickListener({ + val selectedIds = mutableListOf() + for (i in 0..listView.count) { + if (listView.isItemChecked(i)) { + selectedIds.add(habitIds[i]) + } + } + + preferences.addWidget(widgetId, selectedIds.toLongArray()) widgetUpdater.updateWidgets() setResult(Activity.RESULT_OK, Intent().apply { putExtra(EXTRA_APPWIDGET_ID, widgetId) @@ -73,16 +82,4 @@ class HabitPickerDialog : Activity(), AdapterView.OnItemClickListener { }) } } - - override fun onItemClick(parent: AdapterView<*>, - view: View, - position: Int, - id: Long) { - preferences.addWidget(widgetId, habitIds[position]) - widgetUpdater.updateWidgets() - setResult(Activity.RESULT_OK, Intent().apply { - putExtra(EXTRA_APPWIDGET_ID, widgetId) - }) - finish() - } } 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 3ba9f4dd2..0f4199b12 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,17 +18,12 @@ */ package org.isoron.uhabits.widgets -import android.content.Context +import android.content.* 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) - if (habit != null) { - return HistoryWidget(context, id, habit) - } else { - return StackWidget(context, id, StackWidgetType.HISTORY) - } + val habits = getHabitsFromWidgetId(id) + if (habits.size == 1) return HistoryWidget(context, id, habits[0]) + else return StackWidget(context, id, StackWidgetType.HISTORY, habits) } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt index 3ee5ed2ba..54ddabaa1 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt @@ -24,15 +24,13 @@ import android.view.* import org.isoron.uhabits.activities.common.views.* import org.isoron.uhabits.activities.habits.show.views.* import org.isoron.uhabits.core.models.* -import org.isoron.uhabits.core.preferences.* import org.isoron.uhabits.utils.* import org.isoron.uhabits.widgets.views.* class ScoreWidget( context: Context, id: Int, - private val habit: Habit, - private val prefs: Preferences + private val habit: Habit ) : BaseWidget(context, id) { override fun getOnClickPendingIntent(context: Context) = 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 63644b0b9..939e23332 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,19 +18,12 @@ */ package org.isoron.uhabits.widgets -import android.content.Context -import org.isoron.uhabits.HabitsApplication +import android.content.* class ScoreWidgetProvider : 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) - val component = (context.applicationContext as HabitsApplication).component - if (habit != null) { - return ScoreWidget(context, id, habit, component.preferences) - } else { - return StackWidget(context, id, StackWidgetType.SCORE) - } + val habits = getHabitsFromWidgetId(id) + if (habits.size == 1) return ScoreWidget(context, id, habits[0]) + else return StackWidget(context, id, StackWidgetType.SCORE, habits) } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt index 3a0aede4c..49d8f69af 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidget.kt @@ -19,17 +19,19 @@ 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 android.appwidget.* +import android.content.* +import android.net.* +import android.view.* +import android.widget.* +import org.isoron.uhabits.core.models.* +import org.isoron.uhabits.core.utils.* class StackWidget( context: Context, widgetId: Int, - private val widgetType: StackWidgetType + private val widgetType: StackWidgetType, + private val habits: List ) : BaseWidget(context, widgetId) { override fun getOnClickPendingIntent(context: Context) = null @@ -39,13 +41,17 @@ class StackWidget( } override fun getRemoteViews(width: Int, height: Int): RemoteViews { + val manager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.packageName, StackWidgetType.getStackWidgetLayoutId(widgetType)) val serviceIntent = Intent(context, StackWidgetService::class.java) + val habitIds = StringUtils.joinLongs(habits.map { it.id!! }.toLongArray()) + serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id) serviceIntent.putExtra(StackWidgetService.WIDGET_TYPE, widgetType.value) - serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))) + serviceIntent.putExtra(StackWidgetService.HABIT_IDS, habitIds) + serviceIntent.data = Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)) remoteViews.setRemoteAdapter(StackWidgetType.getStackWidgetAdapterViewId(widgetType), serviceIntent) - AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(id, StackWidgetType.getStackWidgetAdapterViewId(widgetType)) + manager.notifyAppWidgetViewDataChanged(id, StackWidgetType.getStackWidgetAdapterViewId(widgetType)) // TODO what should the empty view look like? remoteViews.setEmptyView(StackWidgetType.getStackWidgetAdapterViewId(widgetType), StackWidgetType.getStackWidgetEmptyViewId(widgetType)) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java index e8fb06f53..e8c4b606a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java @@ -1,110 +1,127 @@ package org.isoron.uhabits.widgets; -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; - -import org.isoron.uhabits.HabitsApplication; -import org.isoron.uhabits.core.models.Habit; - -import java.util.ArrayList; - -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.StackWidgetService.WIDGET_TYPE; +import android.appwidget.*; +import android.content.*; +import android.os.*; +import android.support.annotation.*; +import android.widget.*; + +import org.isoron.uhabits.*; +import org.isoron.uhabits.core.models.*; +import org.isoron.uhabits.core.utils.*; -public class StackWidgetService extends RemoteViewsService { +import java.util.*; + +import static android.appwidget.AppWidgetManager.*; +import static org.isoron.androidbase.utils.InterfaceUtils.dpToPixels; +import static org.isoron.uhabits.widgets.StackWidgetService.*; +public class StackWidgetService extends RemoteViewsService +{ public static final String WIDGET_TYPE = "WIDGET_TYPE"; + public static final String HABIT_IDS = "HABIT_IDS"; @Override - public RemoteViewsFactory onGetViewFactory(Intent intent) { + public RemoteViewsFactory onGetViewFactory(Intent intent) + { return new StackRemoteViewsFactory(this.getApplicationContext(), intent); } } -class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { - private Context mContext; - private int mAppWidgetId; - private ArrayList mHabitList; - private StackWidgetType mWidgetType; - - public StackRemoteViewsFactory(Context context, Intent intent) { - mContext = context; - mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); +class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory +{ + private Context context; + private int widgetId; + private long[] habitIds; + private ArrayList habits = new ArrayList<>(); + private StackWidgetType widgetType; + + public StackRemoteViewsFactory(Context context, Intent intent) + { + this.context = context; + widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); int widgetTypeValue = intent.getIntExtra(WIDGET_TYPE, -1); - if (widgetTypeValue != -1) { - mWidgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue); - } + String habitIdsStr = intent.getStringExtra(HABIT_IDS); + + if (widgetTypeValue < 0) throw new RuntimeException("invalid widget type"); + if (habitIdsStr == null) throw new RuntimeException("habitIdsStr is null"); + + widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue); + habitIds = StringUtils.splitLongs(habitIdsStr); } - public void onCreate() { + public void onCreate() + { } - public void onDestroy() { + public void onDestroy() + { } - public int getCount() { - return mHabitList.size(); + public int getCount() + { + return habits.size(); } @NonNull public WidgetDimensions getDimensionsFromOptions(@NonNull Context ctx, - @NonNull Bundle options) { + @NonNull Bundle options) + { int maxWidth = - (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_WIDTH)); + (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_WIDTH)); int maxHeight = - (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_HEIGHT)); + (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MAX_HEIGHT)); int minWidth = - (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_WIDTH)); + (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_WIDTH)); int minHeight = - (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_HEIGHT)); + (int) dpToPixels(ctx, options.getInt(OPTION_APPWIDGET_MIN_HEIGHT)); return new WidgetDimensions(minWidth, maxHeight, maxWidth, minHeight); } - public RemoteViews getViewAt(int position) { + public RemoteViews getViewAt(int position) + { RemoteViews rv = null; - if (position < getCount()) { - Habit habit = mHabitList.get(position); + if (position < getCount()) + { + Habit habit = habits.get(position); BaseWidget widget = initializeWidget(habit); - Bundle options = AppWidgetManager.getInstance(mContext).getAppWidgetOptions(mAppWidgetId); - widget.setDimensions(getDimensionsFromOptions(mContext, options)); + Bundle options = + AppWidgetManager.getInstance(context).getAppWidgetOptions(widgetId); + widget.setDimensions(getDimensionsFromOptions(context, 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 { + new Handler(Looper.getMainLooper()).post(() -> + { + 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) { - + } + catch (InterruptedException e) + { + // ignored } } } @@ -115,44 +132,55 @@ class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { return rv; } - private BaseWidget initializeWidget(Habit habit) { - switch (mWidgetType) { + private BaseWidget initializeWidget(Habit habit) + { + switch (widgetType) + { case CHECKMARK: - return new CheckmarkWidget(mContext, mAppWidgetId, habit); + return new CheckmarkWidget(context, widgetId, habit); case FREQUENCY: - return new FrequencyWidget(mContext, mAppWidgetId, habit); + return new FrequencyWidget(context, widgetId, habit); case SCORE: - HabitsApplication app = (HabitsApplication) mContext.getApplicationContext(); - return new ScoreWidget(mContext, mAppWidgetId, habit, app.getComponent().getPreferences()); + return new ScoreWidget(context, widgetId, habit); case HISTORY: - return new HistoryWidget(mContext, mAppWidgetId, habit); + return new HistoryWidget(context, widgetId, habit); case STREAKS: - return new StreakWidget(mContext, mAppWidgetId, habit); + return new StreakWidget(context, widgetId, habit); } return null; } - public RemoteViews getLoadingView() { + public RemoteViews getLoadingView() + { return null; } - public int getViewTypeCount() { + public int getViewTypeCount() + { return 1; } - public long getItemId(int position) { + public long getItemId(int position) + { return position; } - public boolean hasStableIds() { + public boolean hasStableIds() + { return false; } - public void onDataSetChanged() { - mHabitList = new ArrayList<>(); - HabitsApplication app = (HabitsApplication) mContext.getApplicationContext(); - for (Habit h : app.getComponent().getHabitList()) { - mHabitList.add(h); + public void onDataSetChanged() + { + habits.clear(); + HabitsApplication app = (HabitsApplication) context.getApplicationContext(); + HabitList habitList = app.getComponent().getHabitList(); + + for (long id : habitIds) + { + Habit h = habitList.getById(id); + if (h == null) throw new HabitNotFoundException(); + habits.add(h); } } } 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 1a2696fff..931c924b6 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,17 +18,12 @@ */ package org.isoron.uhabits.widgets -import android.content.Context +import android.content.* 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) - if (habit != null) { - return StreakWidget(context, id, habit) - } else { - return StackWidget(context, id, StackWidgetType.STREAKS) - } + val habits = getHabitsFromWidgetId(id) + if (habits.size == 1) return StreakWidget(context, id, habits[0]) + else return StackWidget(context, id, StackWidgetType.STREAKS, habits) } } 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 6681ffaf4..a85ea9ad4 100644 --- a/uhabits-android/src/main/res/layout/widget_configure_activity.xml +++ b/uhabits-android/src/main/res/layout/widget_configure_activity.xml @@ -22,12 +22,6 @@ android:layout_height="match_parent" android:orientation="vertical"> -