Skip to content

Commit

Permalink
Use skeleton view when loading images (#3726)
Browse files Browse the repository at this point in the history
Signed-off-by: mueller-ma <[email protected]>
  • Loading branch information
mueller-ma authored Jul 2, 2024
1 parent 143fe53 commit a696088
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.util.Base64
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import com.faltenreich.skeletonlayout.Skeleton
import com.github.chrisbanes.photoview.PhotoView
import kotlin.math.max
import kotlinx.coroutines.Dispatchers
Expand All @@ -40,6 +41,7 @@ import org.openhab.habdroid.util.orDefaultIfEmpty

class ImageWidgetActivity : AbstractBaseActivity() {
private lateinit var imageView: PhotoView
private lateinit var skeleton: Skeleton
private var connection: Connection? = null
private var refreshJob: Job? = null
private var delay: Long = 0
Expand All @@ -52,7 +54,9 @@ class ImageWidgetActivity : AbstractBaseActivity() {
supportActionBar?.title =
intent.getStringExtra(WIDGET_LABEL).orDefaultIfEmpty(getString(R.string.widget_type_image))

imageView = findViewById(R.id.activity_content)
imageView = findViewById(R.id.photo_view)
skeleton = findViewById(R.id.activity_content)

delay = intent.getIntExtra(WIDGET_REFRESH, 0).toLong()
}

Expand Down Expand Up @@ -106,6 +110,7 @@ class ImageWidgetActivity : AbstractBaseActivity() {
private suspend fun loadImage() {
val widgetUrl = intent.getStringExtra(WIDGET_URL)
val conn = connection ?: return finish()
skeleton.showSkeleton()
val bitmap = if (widgetUrl != null) {
Log.d(TAG, "Load image from url")
val displayMetrics = resources.displayMetrics
Expand Down Expand Up @@ -149,6 +154,7 @@ class ImageWidgetActivity : AbstractBaseActivity() {
imageView.getSuppMatrix(matrix)
imageView.setImageBitmap(bitmap)
imageView.setSuppMatrix(matrix)
skeleton.showOriginal()
}

private fun scheduleRefresh() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import android.util.AttributeSet
import android.util.Base64
import android.util.Log
import androidx.appcompat.widget.AppCompatImageView
import com.faltenreich.skeletonlayout.Skeleton
import com.faltenreich.skeletonlayout.SkeletonLayout
import com.faltenreich.skeletonlayout.createSkeleton
import kotlin.random.Random
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -43,8 +46,8 @@ import org.openhab.habdroid.util.isDebugModeEnabled
class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageView(context, attrs) {
private var scope: CoroutineScope? = null
private val fallback: Drawable?
private val progressDrawable: Drawable?

private var skeleton: Skeleton? = null
private var originalScaleType: ScaleType? = null
private var originalAdjustViewBounds: Boolean = false
private val emptyHeightToWidthRatio: Float
Expand All @@ -64,7 +67,6 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
init {
context.obtainStyledAttributes(attrs, R.styleable.WidgetImageView).apply {
fallback = getDrawable(R.styleable.WidgetImageView_fallback)
progressDrawable = getDrawable(R.styleable.WidgetImageView_progressIndicator)
emptyHeightToWidthRatio = getFraction(R.styleable.WidgetImageView_emptyHeightToWidthRatio, 1, 1, 0f)
addRandomnessToUrl = getBoolean(R.styleable.WidgetImageView_addRandomnessToUrl, false)
val imageScalingType = getInt(R.styleable.WidgetImageView_imageScalingType, 0)
Expand All @@ -73,6 +75,12 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
}
recycle()
}
// In some cases it's required to add the skeleton manually to XML.
// In these cases, set the parent as skeleton here, otherwise create it in applyProgressDrawable()
val parent = parent
if (parent is SkeletonLayout) {
skeleton = parent
}
}

fun setImageUrl(
Expand Down Expand Up @@ -166,9 +174,7 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val d = drawable
val isEmpty = d == null || d === progressDrawable

if (isEmpty && emptyHeightToWidthRatio > 0) {
if (d == null && emptyHeightToWidthRatio > 0) {
val specWidth = MeasureSpec.getSize(widthMeasureSpec)
val specMode = MeasureSpec.getMode(widthMeasureSpec)
if (specMode == MeasureSpec.AT_MOST || specMode == MeasureSpec.EXACTLY) {
Expand Down Expand Up @@ -240,7 +246,7 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
cancelRefresh()
lastRequest = null
refreshInterval = 0
removeProgressDrawable()
removeSkeleton()
}

private fun doLoad(client: HttpClient, url: HttpUrl, timeoutMillis: Long, forceLoad: Boolean) {
Expand All @@ -254,8 +260,8 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi

if (cached != null) {
applyLoadedBitmap(cached)
} else if (progressDrawable != null || lastRequest?.statelessUrlEquals(url) != true) {
applyProgressDrawable()
} else if (lastRequest?.statelessUrlEquals(url) != true) {
applySkeleton()
}

if (cached == null || forceLoad) {
Expand Down Expand Up @@ -287,7 +293,7 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
}

private fun applyLoadedBitmap(bitmap: Bitmap) {
removeProgressDrawable()
removeSkeleton()
if (imageScalingType == ImageScalingType.ScaleToFitWithViewAdjustmentDownscaleOnly) {
// Make sure that view only shrinks to accommodate bitmap size, but doesn't enlarge ... that is,
// adjust view bounds only if width is larger than target size or height is larger than the maximum height
Expand All @@ -309,22 +315,15 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
super.setImageDrawable(fallback)
}

private fun applyProgressDrawable() {
if (originalScaleType == null) {
originalScaleType = scaleType
super.setScaleType(ScaleType.CENTER)
super.setAdjustViewBounds(false)
private fun applySkeleton() {
if (skeleton == null) {
skeleton = createSkeleton()
}
super.setImageDrawable(progressDrawable)
skeleton?.showSkeleton()
}

private fun removeProgressDrawable() {
if (originalScaleType != null) {
super.setAdjustViewBounds(originalAdjustViewBounds)
super.setScaleType(originalScaleType)
originalScaleType = null
}
super.setImageDrawable(null)
private fun removeSkeleton() {
skeleton?.showOriginal()
}

private inner class HttpImageRequest(
Expand Down Expand Up @@ -378,7 +377,7 @@ class WidgetImageView(context: Context, attrs: AttributeSet?) : AppCompatImageVi
if (context.getPrefs().isDebugModeEnabled()) {
Log.d(TAG, "Failed to load image '$url', HTTP code ${e.statusCode}", e)
}
removeProgressDrawable()
removeSkeleton()
applyFallbackDrawable()
}
}
Expand Down
13 changes: 0 additions & 13 deletions mobile/src/main/res/drawable-night/ic_image_loading_themed.xml

This file was deleted.

13 changes: 0 additions & 13 deletions mobile/src/main/res/drawable/ic_image_loading_themed.xml

This file was deleted.

17 changes: 11 additions & 6 deletions mobile/src/main/res/layout/activity_chart.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
Expand All @@ -14,13 +15,17 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<org.openhab.habdroid.ui.widget.WidgetImageView
android:id="@+id/chart"
<com.faltenreich.skeletonlayout.SkeletonLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:imageScalingType="scaleToFitWithViewAdjustment"
app:progressIndicator="@drawable/ic_image_loading_themed"
app:addRandomnessToUrl="true" />
android:layout_height="match_parent">
<org.openhab.habdroid.ui.widget.WidgetImageView
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:imageScalingType="scaleToFitWithViewAdjustment"
app:addRandomnessToUrl="true"
tools:src="@drawable/day_dream_preview" />
</com.faltenreich.skeletonlayout.SkeletonLayout>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Expand Down
11 changes: 9 additions & 2 deletions mobile/src/main/res/layout/activity_image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@

<include layout="@layout/app_bar" />

<com.github.chrisbanes.photoview.PhotoView
<com.faltenreich.skeletonlayout.SkeletonLayout
android:id="@+id/activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/photo_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</com.faltenreich.skeletonlayout.SkeletonLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>
1 change: 0 additions & 1 deletion mobile/src/main/res/layout/itempickerlist_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
android:layout_height="40dp"
android:layout_gravity="center_vertical"
app:imageScalingType="noScaling"
app:progressIndicator="@drawable/ic_openhab_appicon_24dp"
app:fallback="@drawable/ic_openhab_appicon_24dp"
tools:src="@drawable/ic_openhab_appicon_24dp" />

Expand Down
1 change: 0 additions & 1 deletion mobile/src/main/res/layout/notificationlist_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
android:layout_height="40dp"
android:layout_gravity="center_vertical"
app:imageScalingType="noScaling"
app:progressIndicator="@drawable/ic_openhab_appicon_24dp"
app:fallback="@drawable/ic_openhab_appicon_24dp"
tools:src="@drawable/ic_openhab_appicon_24dp" />

Expand Down
1 change: 0 additions & 1 deletion mobile/src/main/res/layout/widgetlist_chartitem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
android:layout_height="wrap_content"
app:imageScalingType="scaleToFitWithViewAdjustment"
app:emptyHeightToWidthRatio="50%"
app:progressIndicator="@drawable/ic_image_loading_themed"
app:addRandomnessToUrl="true" />

<include layout="@layout/widgetlist_data_saver" />
Expand Down
3 changes: 1 addition & 2 deletions mobile/src/main/res/layout/widgetlist_imageitem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
<org.openhab.habdroid.ui.widget.WidgetImageView
android:id="@+id/widget_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:progressIndicator="@drawable/ic_image_loading_themed" />
android:layout_height="wrap_content" />

<include layout="@layout/widgetlist_data_saver" />

Expand Down
3 changes: 1 addition & 2 deletions mobile/src/main/res/layout/widgetlist_videomjpegitem.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/content_description_video"
app:imageScalingType="scaleToFitWithViewAdjustment"
app:progressIndicator="@drawable/ic_image_loading_themed" />
app:imageScalingType="scaleToFitWithViewAdjustment" />

<include layout="@layout/widgetlist_data_saver" />

Expand Down
1 change: 0 additions & 1 deletion mobile/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<resources>
<declare-styleable name="WidgetImageView">
<attr name="fallback" format="reference" />
<attr name="progressIndicator" format="reference" />
<attr name="emptyHeightToWidthRatio" format="fraction" />
<attr name="addRandomnessToUrl" format="boolean" />
<attr name="imageScalingType" format="enum">
Expand Down

0 comments on commit a696088

Please sign in to comment.