From 8feb07ff1bfcde3d46fb3f8a30926e1b6f8c5b64 Mon Sep 17 00:00:00 2001 From: Victor Yu Date: Wed, 8 Nov 2017 21:03:06 -0500 Subject: [PATCH] Code review changes; Made 'stack view' design available for all widgets --- android-base/build.gradle | 1 + android-pickers/build.gradle | 1 + build.gradle | 2 +- uhabits-android/build.gradle | 1 + uhabits-android/src/main/AndroidManifest.xml | 9 +- .../uhabits/widgets/BaseWidgetProvider.java | 4 +- .../widgets/CheckmarkStackWidgetProvider.kt | 19 --- .../widgets/CheckmarkWidgetProvider.kt | 21 +-- .../widgets/FrequencyWidgetProvider.kt | 10 +- .../uhabits/widgets/HabitGroupPickerDialog.kt | 133 ------------------ .../uhabits/widgets/HabitPickerDialog.kt | 11 ++ .../uhabits/widgets/HistoryWidgetProvider.kt | 10 +- .../uhabits/widgets/ScoreWidgetProvider.kt | 14 +- ...CheckmarkStackWidget.kt => StackWidget.kt} | 20 +-- ...etService.java => StackWidgetService.java} | 83 ++++++++--- .../uhabits/widgets/StackWidgetType.java | 89 ++++++++++++ .../uhabits/widgets/StreakWidgetProvider.kt | 10 +- ...get.xml => checkmark_stackview_widget.xml} | 4 +- .../res/layout/frequency_stackview_widget.xml | 19 +++ .../res/layout/history_stackview_widget.xml | 19 +++ .../res/layout/score_stackview_widget.xml | 19 +++ .../res/layout/streak_stackview_widget.xml | 19 +++ .../res/layout/widget_configure_activity.xml | 28 ++-- .../src/main/res/values/strings.xml | 6 + .../main/res/xml/widget_checkmark_info.xml | 2 +- .../core/preferences/WidgetPreferences.java | 36 +---- 26 files changed, 332 insertions(+), 258 deletions(-) delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkStackWidgetProvider.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/widgets/HabitGroupPickerDialog.kt rename uhabits-android/src/main/java/org/isoron/uhabits/widgets/{CheckmarkStackWidget.kt => StackWidget.kt} (67%) rename uhabits-android/src/main/java/org/isoron/uhabits/widgets/{CheckmarkStackWidgetService.java => StackWidgetService.java} (52%) create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java rename uhabits-android/src/main/res/layout/{stackview_widget.xml => checkmark_stackview_widget.xml} (86%) create mode 100644 uhabits-android/src/main/res/layout/frequency_stackview_widget.xml create mode 100644 uhabits-android/src/main/res/layout/history_stackview_widget.xml create mode 100644 uhabits-android/src/main/res/layout/score_stackview_widget.xml create mode 100644 uhabits-android/src/main/res/layout/streak_stackview_widget.xml 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 +