diff --git a/mobile/build.gradle b/mobile/build.gradle index 321488ac4e..d411b8acbb 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -174,7 +174,8 @@ dependencies { implementation "com.github.QuadFlask:colorpicker:0.0.15" implementation "com.caverock:androidsvg-aar:1.4" implementation "com.github.AppIntro:AppIntro:6.3.1" - implementation 'com.github.chrisbanes:PhotoView:2.3.0' + implementation "com.github.chrisbanes:PhotoView:2.3.0" + implementation "com.faltenreich:skeletonlayout:5.0.0" // MapView support fullImplementation "com.google.android.gms:play-services-maps:18.2.0" fossImplementation "org.osmdroid:osmdroid-android:6.1.18" diff --git a/mobile/src/main/java/org/openhab/habdroid/ui/CloudNotificationListFragment.kt b/mobile/src/main/java/org/openhab/habdroid/ui/CloudNotificationListFragment.kt index 91d2c1399a..c2bdd55667 100644 --- a/mobile/src/main/java/org/openhab/habdroid/ui/CloudNotificationListFragment.kt +++ b/mobile/src/main/java/org/openhab/habdroid/ui/CloudNotificationListFragment.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.ImageView +import android.widget.LinearLayout import android.widget.TextView import androidx.core.os.bundleOf import androidx.core.view.isVisible @@ -28,6 +29,7 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.faltenreich.skeletonlayout.SkeletonLayout import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.json.JSONArray @@ -50,6 +52,7 @@ import org.openhab.habdroid.util.map */ class CloudNotificationListFragment : Fragment(), View.OnClickListener, SwipeRefreshLayout.OnRefreshListener { lateinit var recyclerView: RecyclerView + private lateinit var skeleton: SkeletonLayout private lateinit var swipeLayout: SwipeRefreshLayout private lateinit var retryButton: Button private lateinit var emptyView: View @@ -71,6 +74,13 @@ class CloudNotificationListFragment : Fragment(), View.OnClickListener, SwipeRef emptyView = view.findViewById(android.R.id.empty) emptyMessage = view.findViewById(R.id.empty_message) emptyWatermark = view.findViewById(R.id.watermark) + skeleton = view.findViewById(R.id.skeletonLayout) + view.findViewById(R.id.skeletonList).apply { + repeat(10) { + addView(inflater.inflate(R.layout.notificationlist_item, null)) + } + } + skeleton.showSkeleton() swipeLayout = view.findViewById(R.id.swipe_container) swipeLayout.setOnRefreshListener(this) @@ -106,6 +116,7 @@ class CloudNotificationListFragment : Fragment(), View.OnClickListener, SwipeRef override fun onRefresh() { Log.d(TAG, "onRefresh()") + swipeLayout.isRefreshing = false loadNotifications(true) } @@ -172,7 +183,7 @@ class CloudNotificationListFragment : Fragment(), View.OnClickListener, SwipeRef val showEmpty = !loading && (adapter.itemCount == 0 || loadError) recyclerView.isVisible = !showEmpty emptyView.isVisible = showEmpty - swipeLayout.isRefreshing = loading + skeleton.isVisible = loading emptyMessage.setText( if (loadError) R.string.notification_list_error else R.string.notification_list_empty ) diff --git a/mobile/src/main/java/org/openhab/habdroid/ui/activity/ContentController.kt b/mobile/src/main/java/org/openhab/habdroid/ui/activity/ContentController.kt index 3ba3781bc5..042b940646 100644 --- a/mobile/src/main/java/org/openhab/habdroid/ui/activity/ContentController.kt +++ b/mobile/src/main/java/org/openhab/habdroid/ui/activity/ContentController.kt @@ -41,6 +41,7 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks import androidx.fragment.app.commit import androidx.fragment.app.commitNow +import com.faltenreich.skeletonlayout.SkeletonLayout import java.util.Stack import org.openhab.habdroid.R import org.openhab.habdroid.core.OpenHabApplication @@ -793,7 +794,9 @@ abstract class ContentController protected constructor(private val activity: Mai descriptionText.text = arguments.getCharSequence(KEY_MESSAGE) descriptionText.isVisible = !descriptionText.text.isNullOrEmpty() - view.findViewById(R.id.progress).isVisible = arguments.getBoolean(KEY_PROGRESS) + val skeleton = view.findViewById(R.id.skeletonLayout) + skeleton.isVisible = arguments.getBoolean(KEY_PROGRESS) + skeleton.showSkeleton() val watermark = view.findViewById(R.id.image) diff --git a/mobile/src/main/res/layout/fragment_notificationlist.xml b/mobile/src/main/res/layout/fragment_notificationlist.xml index 99fcfbda99..de85e15c31 100644 --- a/mobile/src/main/res/layout/fragment_notificationlist.xml +++ b/mobile/src/main/res/layout/fragment_notificationlist.xml @@ -54,6 +54,18 @@ + + + + + diff --git a/mobile/src/main/res/layout/fragment_status.xml b/mobile/src/main/res/layout/fragment_status.xml index bdc9e7f68b..88411c42e2 100644 --- a/mobile/src/main/res/layout/fragment_status.xml +++ b/mobile/src/main/res/layout/fragment_status.xml @@ -34,13 +34,39 @@ android:textColor="?colorOnSurfaceVariant" tools:text="Some status message" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + +