diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-07-03 01:43:09 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-07-15 12:52:17 +0000 |
| commit | 32f7c8beb8aeb402d080ff0438c8b599e9a14b09 (patch) | |
| tree | 51c2fa90c1f44aec0940fda070696ef149b87090 /android | |
| parent | dd2caa1ace19637408570da1409b5b0ea78ba1cc (diff) | |
| download | mullvadvpn-32f7c8beb8aeb402d080ff0438c8b599e9a14b09.tar.xz mullvadvpn-32f7c8beb8aeb402d080ff0438c8b599e9a14b09.zip | |
Show spinner while list is loading
Diffstat (limited to 'android')
3 files changed, 61 insertions, 3 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/applist/AppListAdapter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/applist/AppListAdapter.kt index 5c44d69654..fe9c223194 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/applist/AppListAdapter.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/applist/AppListAdapter.kt @@ -14,6 +14,11 @@ class AppListAdapter(context: Context) : Adapter<AppListItemHolder>() { private val packageManager = context.packageManager private val thisPackageName = context.packageName + var onListReady: (suspend () -> Unit)? = null + + var isListReady = false + private set + var enabled by observable(false) { _, oldValue, newValue -> if (oldValue != newValue) { if (newValue == true) { @@ -56,6 +61,8 @@ class AppListAdapter(context: Context) : Adapter<AppListItemHolder>() { } jobTracker.newUiJob("notifyAppListChanges") { + isListReady = true + onListReady?.invoke() notifyItemRangeInserted(0, applications.size) } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SplitTunnellingFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SplitTunnellingFragment.kt index de095b2fc0..4c5e1ef98f 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SplitTunnellingFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SplitTunnellingFragment.kt @@ -21,18 +21,32 @@ class SplitTunnellingFragment : ServiceDependentFragment(OnNoService.GoToLaunchS override fun onAnimationStart(animation: Animator) {} override fun onAnimationEnd(animation: Animator) { - if (!appListAdapter.enabled) { + if (!appListAdapter.enabled && appListAdapter.isListReady) { excludeApplications.visibility = View.GONE } } } + private val loadingSpinnerFadeOutListener = object : AnimatorListener { + override fun onAnimationCancel(animation: Animator) {} + override fun onAnimationRepeat(animation: Animator) {} + override fun onAnimationStart(animation: Animator) {} + + override fun onAnimationEnd(animation: Animator) { + if (appListAdapter.isListReady) { + appListAdapter.enabled = true + loadingSpinner.visibility = View.GONE + } + } + } + private lateinit var appListAdapter: AppListAdapter private lateinit var excludeApplicationsFadeOut: ObjectAnimator - + private lateinit var loadingSpinnerFadeIn: ObjectAnimator private lateinit var titleController: CollapsibleTitleController private lateinit var excludeApplications: View + private lateinit var loadingSpinner: View override fun onAttach(context: Context) { super.onAttach(context) @@ -75,6 +89,7 @@ class SplitTunnellingFragment : ServiceDependentFragment(OnNoService.GoToLaunchS private fun configureHeader(header: View) { excludeApplications = header.findViewById(R.id.exclude_applications) + loadingSpinner = header.findViewById(R.id.loading_spinner) excludeApplicationsFadeOut = ObjectAnimator.ofFloat(excludeApplications, "alpha", 1.0f, 0.0f).apply { @@ -82,6 +97,12 @@ class SplitTunnellingFragment : ServiceDependentFragment(OnNoService.GoToLaunchS setDuration(200) } + loadingSpinnerFadeIn = + ObjectAnimator.ofFloat(loadingSpinner, "alpha", 0.0f, 1.0f).apply { + addListener(loadingSpinnerFadeOutListener) + setDuration(200) + } + header.findViewById<CellSwitch>(R.id.enabled_toggle).listener = { toggleState -> when (toggleState) { CellSwitch.State.ON -> enable() @@ -91,7 +112,18 @@ class SplitTunnellingFragment : ServiceDependentFragment(OnNoService.GoToLaunchS } private fun enable() { - appListAdapter.enabled = true + appListAdapter.apply { + if (!isListReady) { + enabled = false + showLoadingSpinner() + onListReady = { + hideLoadingSpinner() + } + } else { + enabled = true + } + } + excludeApplications.visibility = View.VISIBLE excludeApplicationsFadeOut.reverse() } @@ -100,4 +132,13 @@ class SplitTunnellingFragment : ServiceDependentFragment(OnNoService.GoToLaunchS appListAdapter.enabled = false excludeApplicationsFadeOut.start() } + + private fun showLoadingSpinner() { + loadingSpinner.visibility = View.VISIBLE + loadingSpinnerFadeIn.start() + } + + private fun hideLoadingSpinner() { + loadingSpinnerFadeIn.reverse() + } } diff --git a/android/src/main/res/layout/split_tunnelling_header.xml b/android/src/main/res/layout/split_tunnelling_header.xml index 48d3e6e831..e6805329e3 100644 --- a/android/src/main/res/layout/split_tunnelling_header.xml +++ b/android/src/main/res/layout/split_tunnelling_header.xml @@ -60,4 +60,14 @@ android:textStyle="bold" android:text="@string/exclude_applications" /> </LinearLayout> + <ProgressBar android:id="@+id/loading_spinner" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_gravity="center" + android:layout_marginTop="24dp" + android:indeterminate="true" + android:indeterminateOnly="true" + android:indeterminateDuration="600" + android:indeterminateDrawable="@drawable/icon_spinner" + android:visibility="gone" /> </LinearLayout> |
