From b77158d2443942684873981df4ec475fa13697f7 Mon Sep 17 00:00:00 2001 From: pauliancu97 <32488931+pauliancu97@users.noreply.github.com> Date: Wed, 10 Nov 2021 15:34:35 +0200 Subject: [PATCH] Bug fix stats widget (#1664) * added resources to run project * fixed problem of user stats not being shown in the widget * refactored some code --- Habitica/AndroidManifest.xml | 3 + Habitica/res/layout/widget_avatar_stats.xml | 3 - .../res/layout/widget_main_avatar_stats.xml | 20 ++ .../habitica/components/UserComponent.java | 3 + .../android/habitica/ui/AvatarView.kt | 16 ++ .../widget/AvatarStatsWidgetFactory.kt | 182 ++++++++++++++++++ .../widget/AvatarStatsWidgetProvider.kt | 122 +++--------- .../widget/AvatarStatsWidgetService.kt | 12 ++ .../habitica/widget/BaseWidgetProvider.kt | 32 +-- 9 files changed, 277 insertions(+), 116 deletions(-) create mode 100644 Habitica/res/layout/widget_main_avatar_stats.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetFactory.kt create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetService.kt diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 20aa8c698..e16895b12 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -286,6 +286,9 @@ + diff --git a/Habitica/res/layout/widget_avatar_stats.xml b/Habitica/res/layout/widget_avatar_stats.xml index 4f738032d..baf438406 100644 --- a/Habitica/res/layout/widget_avatar_stats.xml +++ b/Habitica/res/layout/widget_avatar_stats.xml @@ -5,11 +5,8 @@ android:id="@+id/widget_main_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:focusable="true" - android:focusableInTouchMode="true" android:background="@drawable/widget_background" android:padding="8dp" - android:elevation="2dp" android:orientation="vertical"> + + + + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java index c24273044..17fc2e8de 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java @@ -109,6 +109,7 @@ import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog; import com.habitrpg.android.habitica.ui.views.social.ChatBarView; import com.habitrpg.android.habitica.ui.views.stats.BulkAllocateStatsDialog; import com.habitrpg.android.habitica.ui.views.tasks.TaskFilterDialog; +import com.habitrpg.android.habitica.widget.AvatarStatsWidgetFactory; import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider; import com.habitrpg.android.habitica.widget.BaseWidgetProvider; import com.habitrpg.android.habitica.widget.DailiesWidgetProvider; @@ -349,4 +350,6 @@ public interface UserComponent { void inject(@NotNull ItemDialogFragment itemDialogFragment); void inject(@NotNull EquipmentOverviewViewModel equipmentOverviewViewModel); + + void inject(@NotNull AvatarStatsWidgetFactory avatarStatsWidgetFactory); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt index b3166efa8..e1620a012 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt @@ -19,7 +19,9 @@ import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.functions.Consumer +import io.reactivex.rxjava3.subjects.PublishSubject import java.util.* import java.util.concurrent.atomic.AtomicInteger @@ -38,6 +40,7 @@ class AvatarView : FrameLayout { private val avatarMatrix = Matrix() private val numberLayersInProcess = AtomicInteger(0) private var avatarImageConsumer: Consumer? = null + private var avatarBitmapSubject: PublishSubject = PublishSubject.create() private var avatarBitmap: Bitmap? = null private var avatarCanvas: Canvas? = null private var currentLayers: Map? = null @@ -400,6 +403,7 @@ class AvatarView : FrameLayout { private fun onLayerComplete() { if (numberLayersInProcess.decrementAndGet() == 0) { avatarImageConsumer?.accept(avatarImage) + avatarImage?.let { avatarBitmapSubject.onNext(it) } } } @@ -407,12 +411,24 @@ class AvatarView : FrameLayout { avatarImageConsumer = consumer if (imageViewHolder.size > 0 && numberLayersInProcess.get() == 0) { avatarImageConsumer?.accept(avatarImage) + avatarImage?.let { avatarBitmapSubject.onNext(it) } } else { initAvatarRectMatrix() showLayers(layerMap) } } + fun createAvatarImage(): Bitmap? { + if (imageViewHolder.size > 0 && numberLayersInProcess.get() == 0) { + avatarImageConsumer?.accept(avatarImage) + avatarImage?.let { avatarBitmapSubject.onNext(it) } + } else { + initAvatarRectMatrix() + showLayers(layerMap) + } + return avatarBitmapSubject.hide().firstElement().blockingGet() + } + fun setAvatar(avatar: Avatar) { val oldUser = this.avatar this.avatar = avatar diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetFactory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetFactory.kt new file mode 100644 index 000000000..0344488ce --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetFactory.kt @@ -0,0 +1,182 @@ +package com.habitrpg.android.habitica.widget + +import android.appwidget.AppWidgetManager +import android.content.Context +import android.os.Handler +import android.view.View +import android.view.ViewGroup +import android.widget.RemoteViews +import android.widget.RemoteViewsService +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.UserRepository +import com.habitrpg.android.habitica.extensions.dpToPx +import com.habitrpg.android.habitica.helpers.HealthFormatter +import com.habitrpg.android.habitica.helpers.NumberAbbreviator +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.user.Stats +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.disposables.CompositeDisposable +import javax.inject.Inject + +class AvatarStatsWidgetFactory( + private val context: Context, + private val widgetId: Int +): RemoteViewsService.RemoteViewsFactory { + + private var isInitialized: Boolean = false + + @Inject + lateinit var userRepository: UserRepository + + private val disposable = CompositeDisposable() + + private var user: User? = null + + private var shouldLoadData: Boolean = false + + private val appWidgetManager = AppWidgetManager.getInstance(context) + + private fun setup() { + if (!isInitialized) { + HabiticaBaseApplication.userComponent?.inject(this) + isInitialized = true + } + } + + private fun loadUser() { + val mainHandler = Handler(context.mainLooper) + mainHandler.post { + disposable.add(userRepository.getUser() + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(AndroidSchedulers.mainThread()) + .subscribe( + { user -> + this.user = user + this.shouldLoadData = false + appWidgetManager.notifyAppWidgetViewDataChanged(widgetId, R.id.widget_avatar_list) + }, + RxErrorHandler.handleEmptyError() + ) + ) + } + } + + private fun getRemoteViewForUser(user: User, stats: Stats): RemoteViews { + val remoteViews = RemoteViews(context.packageName, R.layout.widget_avatar_stats) + + val options = appWidgetManager.getAppWidgetOptions(widgetId) + val minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH) + val minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT) + val cols = BaseWidgetProvider.getCellsForSize(minWidth) + val rows = BaseWidgetProvider.getCellsForSize(minHeight) + + val showAvatar = cols > 3 + val showManaBar = rows > 1 + + val currentHealth = HealthFormatter.format(stats.hp ?: 0.0) + val currentHealthString = HealthFormatter.formatToString(stats.hp ?: 0.0) + val healthValueString = currentHealthString + "/" + stats.maxHealth + val expValueString = "" + stats.exp?.toInt() + "/" + stats.toNextLevel + val mpValueString = "" + stats.mp?.toInt() + "/" + stats.maxMP + + remoteViews.setTextViewText(R.id.TV_hp_value, healthValueString) + remoteViews.setTextViewText(R.id.exp_TV_value, expValueString) + remoteViews.setTextViewText(R.id.mp_TV_value, mpValueString) + + remoteViews.setImageViewBitmap(R.id.ic_hp_header, HabiticaIconsHelper.imageOfHeartLightBg()) + remoteViews.setImageViewBitmap(R.id.ic_exp_header, HabiticaIconsHelper.imageOfExperience()) + remoteViews.setImageViewBitmap(R.id.ic_mp_header, HabiticaIconsHelper.imageOfMagic()) + + remoteViews.setProgressBar(R.id.hp_bar, stats.maxHealth ?: 0, currentHealth.toInt(), false) + remoteViews.setProgressBar(R.id.exp_bar, stats.toNextLevel ?: 0, stats.exp?.toInt() ?: 0, false) + remoteViews.setProgressBar(R.id.mp_bar, stats.maxMP ?: 0, stats.mp?.toInt() ?: 0, false) + remoteViews.setViewVisibility(R.id.mp_wrapper, if (showManaBar && (stats.habitClass == null || (stats.lvl ?: 0) < 10 || user.preferences?.disableClasses == true)) View.GONE else View.VISIBLE) + + remoteViews.setTextViewText(R.id.gold_tv, NumberAbbreviator.abbreviate(context, stats.gp ?: 0.0)) + remoteViews.setTextViewText(R.id.gems_tv, (user.balance * 4).toInt().toString()) + val hourGlassCount = user.hourglassCount + if (hourGlassCount == 0) { + remoteViews.setViewVisibility(R.id.hourglass_icon, View.GONE) + remoteViews.setViewVisibility(R.id.hourglasses_tv, View.GONE) + } else { + remoteViews.setImageViewBitmap(R.id.hourglass_icon, HabiticaIconsHelper.imageOfHourglass()) + remoteViews.setViewVisibility(R.id.hourglass_icon, View.VISIBLE) + remoteViews.setTextViewText(R.id.hourglasses_tv, hourGlassCount.toString()) + remoteViews.setViewVisibility(R.id.hourglasses_tv, View.VISIBLE) + } + remoteViews.setImageViewBitmap(R.id.gem_icon, HabiticaIconsHelper.imageOfGem()) + remoteViews.setImageViewBitmap(R.id.gold_icon, HabiticaIconsHelper.imageOfGold()) + remoteViews.setTextViewText(R.id.lvl_tv, context.getString(R.string.user_level, user.stats?.lvl ?: 0)) + + if (showAvatar) { + val avatarView = + AvatarView(context, showBackground = true, showMount = true, showPet = true) + val layoutParams = ViewGroup.LayoutParams(140.dpToPx(context), 147.dpToPx(context)) + avatarView.layoutParams = layoutParams + avatarView.setAvatar(user) + avatarView.createAvatarImage()?.let { bitmap -> + remoteViews.setImageViewBitmap(R.id.avatar_view, bitmap) + } + + } + + if (showAvatar) { + remoteViews.setViewVisibility(R.id.avatar_view, View.VISIBLE) + } else { + remoteViews.setViewVisibility(R.id.avatar_view, View.GONE) + } + + if (showManaBar) { + remoteViews.setViewVisibility(R.id.detail_info_view, View.VISIBLE) + } else { + remoteViews.setViewVisibility(R.id.detail_info_view, View.GONE) + } + + return remoteViews + } + + override fun onCreate() { + setup() + loadUser() + } + + override fun onDestroy() { + disposable.clear() + } + + override fun onDataSetChanged() { + if (shouldLoadData) { + loadUser() + } + shouldLoadData = true + } + + override fun getCount(): Int { + return 1 + } + + override fun getViewAt(p0: Int): RemoteViews { + val user = this.user + val stats = user?.stats + return if (user != null && stats != null) { + getRemoteViewForUser(user, stats) + } else { + RemoteViews(context.packageName, R.layout.widget_avatar_stats) + } + } + + + override fun getLoadingView() = RemoteViews(context.packageName, R.layout.widget_avatar_stats) + + override fun getViewTypeCount(): Int { + return 1 + } + + override fun getItemId(position: Int) = position.toLong() + + override fun hasStableIds() = true +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt index ceb4369a8..25af7aec0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt @@ -2,32 +2,21 @@ package com.habitrpg.android.habitica.widget import android.app.PendingIntent import android.appwidget.AppWidgetManager -import android.content.ComponentName import android.content.Context import android.content.Intent -import android.view.View -import android.view.ViewGroup +import android.net.Uri +import android.os.Bundle import android.widget.RemoteViews import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.extensions.dpToPx -import com.habitrpg.android.habitica.helpers.HealthFormatter -import com.habitrpg.android.habitica.helpers.NumberAbbreviator -import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.AvatarView import com.habitrpg.android.habitica.ui.activities.MainActivity -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper class AvatarStatsWidgetProvider : BaseWidgetProvider() { private var appWidgetManager: AppWidgetManager? = null - private var showManaBar: Boolean = true - private var showAvatar: Boolean = true - override fun layoutResourceId(): Int { - return R.layout.widget_avatar_stats + return R.layout.widget_main_avatar_stats } private fun setUp() { @@ -38,100 +27,35 @@ class AvatarStatsWidgetProvider : BaseWidgetProvider() { } override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { - super.onUpdate(context, appWidgetManager, appWidgetIds) this.setUp() this.appWidgetManager = appWidgetManager this.context = context + for (widgetId in appWidgetIds) { - userRepository.getUser().firstElement()?.subscribe({ this.updateData(it) }, RxErrorHandler.handleEmptyError()) - } - - override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews { - showAvatar = columns > 3 - if (showAvatar) { - remoteViews.setViewVisibility(R.id.avatar_view, View.VISIBLE) - } else { - remoteViews.setViewVisibility(R.id.avatar_view, View.GONE) - } - - showManaBar = rows > 1 - if (rows > 1) { - remoteViews.setViewVisibility(R.id.detail_info_view, View.VISIBLE) - } else { - remoteViews.setViewVisibility(R.id.detail_info_view, View.GONE) - } - - return remoteViews - } - - private fun updateData(user: User?) { - val context = context - val appWidgetManager = appWidgetManager - val stats = user?.stats - if (user == null || stats == null || context == null || appWidgetManager == null) { - return - } - val thisWidget = ComponentName(context, AvatarStatsWidgetProvider::class.java) - val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) - val currentHealth = HealthFormatter.format(stats.hp ?: 0.0) - val currentHealthString = HealthFormatter.formatToString(stats.hp ?: 0.0) - val healthValueString = currentHealthString + "/" + stats.maxHealth - val expValueString = "" + stats.exp?.toInt() + "/" + stats.toNextLevel - val mpValueString = "" + stats.mp?.toInt() + "/" + stats.maxMP - - for (widgetId in allWidgetIds) { - var remoteViews = RemoteViews(context.packageName, R.layout.widget_avatar_stats) - - remoteViews.setTextViewText(R.id.TV_hp_value, healthValueString) - remoteViews.setTextViewText(R.id.exp_TV_value, expValueString) - remoteViews.setTextViewText(R.id.mp_TV_value, mpValueString) - - remoteViews.setImageViewBitmap(R.id.ic_hp_header, HabiticaIconsHelper.imageOfHeartLightBg()) - remoteViews.setImageViewBitmap(R.id.ic_exp_header, HabiticaIconsHelper.imageOfExperience()) - remoteViews.setImageViewBitmap(R.id.ic_mp_header, HabiticaIconsHelper.imageOfMagic()) - - remoteViews.setProgressBar(R.id.hp_bar, stats.maxHealth ?: 0, currentHealth.toInt(), false) - remoteViews.setProgressBar(R.id.exp_bar, stats.toNextLevel ?: 0, stats.exp?.toInt() ?: 0, false) - remoteViews.setProgressBar(R.id.mp_bar, stats.maxMP ?: 0, stats.mp?.toInt() ?: 0, false) - remoteViews.setViewVisibility(R.id.mp_wrapper, if (showManaBar && (stats.habitClass == null || (stats.lvl ?: 0) < 10 || user.preferences?.disableClasses == true)) View.GONE else View.VISIBLE) - - remoteViews.setTextViewText(R.id.gold_tv, NumberAbbreviator.abbreviate(context, stats.gp ?: 0.0)) - remoteViews.setTextViewText(R.id.gems_tv, (user.balance * 4).toInt().toString()) - val hourGlassCount = user.hourglassCount - if (hourGlassCount == 0) { - remoteViews.setViewVisibility(R.id.hourglass_icon, View.GONE) - remoteViews.setViewVisibility(R.id.hourglasses_tv, View.GONE) - } else { - remoteViews.setImageViewBitmap(R.id.hourglass_icon, HabiticaIconsHelper.imageOfHourglass()) - remoteViews.setViewVisibility(R.id.hourglass_icon, View.VISIBLE) - remoteViews.setTextViewText(R.id.hourglasses_tv, hourGlassCount.toString()) - remoteViews.setViewVisibility(R.id.hourglasses_tv, View.VISIBLE) - } - remoteViews.setImageViewBitmap(R.id.gem_icon, HabiticaIconsHelper.imageOfGem()) - remoteViews.setImageViewBitmap(R.id.gold_icon, HabiticaIconsHelper.imageOfGold()) - remoteViews.setTextViewText(R.id.lvl_tv, context.getString(R.string.user_level, user.stats?.lvl ?: 0)) - - if (showAvatar) { - val avatarView = - AvatarView(context, showBackground = true, showMount = true, showPet = true) - val layoutParams = ViewGroup.LayoutParams(140.dpToPx(context), 147.dpToPx(context)) - avatarView.layoutParams = layoutParams - avatarView.setAvatar(user) - val finalRemoteViews = remoteViews - avatarView.onAvatarImageReady { bitmap -> - finalRemoteViews.setImageViewBitmap(R.id.avatar_view, bitmap) - appWidgetManager.partiallyUpdateAppWidget(allWidgetIds, finalRemoteViews) - } - } + val intent = Intent(context, AvatarStatsWidgetService::class.java) + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId) + intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)) val openAppIntent = Intent(context.applicationContext, MainActivity::class.java) val openApp = PendingIntent.getActivity(context, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT) - remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp) - - val options = appWidgetManager.getAppWidgetOptions(widgetId) - remoteViews = sizeRemoteViews(context, options, widgetId) + val remoteViews = RemoteViews(context.packageName, R.layout.widget_main_avatar_stats) + remoteViews.setRemoteAdapter(R.id.widget_avatar_list, intent) + remoteViews.setEmptyView(R.id.widget_avatar_list, R.id.widget_avatar_empty_view) + remoteViews.setOnClickPendingIntent(R.id.widget_main_avatar_view, openApp) appWidgetManager.updateAppWidget(widgetId, remoteViews) + appWidgetManager.notifyAppWidgetViewDataChanged(widgetId, R.id.widget_avatar_list) } } + + override fun onAppWidgetOptionsChanged( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int, + newOptions: Bundle + ) { + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_avatar_list) + } + + override fun configureRemoteViews(remoteViews: RemoteViews, widgetId: Int, columns: Int, rows: Int): RemoteViews = remoteViews } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetService.kt new file mode 100644 index 000000000..167b5745c --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetService.kt @@ -0,0 +1,12 @@ +package com.habitrpg.android.habitica.widget + +import android.appwidget.AppWidgetManager +import android.content.Intent +import android.widget.RemoteViewsService + +class AvatarStatsWidgetService : RemoteViewsService() { + override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { + val widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0) + return AvatarStatsWidgetFactory(this.applicationContext, widgetId) + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt index 9f45144a3..ecaa6e5b4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/BaseWidgetProvider.kt @@ -15,6 +15,23 @@ import javax.inject.Inject abstract class BaseWidgetProvider : AppWidgetProvider() { + companion object { + /** + * Returns number of cells needed for given size of the widget.

+ * see http://stackoverflow.com/questions/14270138/dynamically-adjusting-widgets-content-and-layout-to-the-size-the-user-defined-t + * + * @param size Widget size in dp. + * @return Size in number of cells. + */ + fun getCellsForSize(size: Int): Int { + var n = 2 + while (70 * n - 30 < size) { + ++n + } + return n - 1 + } + } + @Inject lateinit var userRepository: UserRepository @@ -22,20 +39,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() { protected var context: Context? = null - /** - * Returns number of cells needed for given size of the widget.

- * see http://stackoverflow.com/questions/14270138/dynamically-adjusting-widgets-content-and-layout-to-the-size-the-user-defined-t - * - * @param size Widget size in dp. - * @return Size in number of cells. - */ - private fun getCellsForSize(size: Int): Int { - var n = 2 - while (70 * n - 30 < size) { - ++n - } - return n - 1 - } + override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) { this.context = context