From e9effbe799f53f06c2893b9c74eaa2871f1436a6 Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Sat, 9 Jan 2021 20:26:23 +0100 Subject: [PATCH] Update animations --- .idea/caches/build_file_checksums.ser | Bin 537 -> 537 bytes app/build.gradle | 4 +- .../ui/fragments/MainFragment.kt | 98 +++++++++++------- .../ui/fragments/SettingsFragment.kt | 33 +++--- .../ui/fragments/tabs/GlanceTabFragment.kt | 35 ++++--- .../ui/fragments/tabs/PreferencesFragment.kt | 20 ++-- .../ui/fragments/tabs/WeatherFragment.kt | 12 +-- .../ui/viewmodels/MainViewModel.kt | 3 - .../main/res/layout/fragment_preferences.xml | 10 +- .../main/res/layout/fragment_tab_glance.xml | 40 ++++--- .../main/res/layout/fragment_tab_weather.xml | 2 +- 11 files changed, 146 insertions(+), 111 deletions(-) diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 23d826d0a3e85383089f636160809626fb492fc4..8ef98d1c89a77cd4198758070ea0685623217c7c 100644 GIT binary patch delta 33 rcmV++0N($Z1epYom;~sZ1?jPzYylCUTB#nC;fxBwL$OIcqFW|-^X3jl delta 33 pcmbQqGLvP(43>K-%u_ec$zc@yK5IsSb4^IxG-e~uE~fK|6#(SO4PF2M diff --git a/app/build.gradle b/app/build.gradle index b7bf1c4..40046e8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,8 +22,8 @@ android { applicationId "com.tommasoberlose.anotherwidget" minSdkVersion 23 targetSdkVersion 30 - versionCode 115 - versionName "2.1.1" + versionCode 116 + versionName "2.2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY']) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt index 14b14a9..039ba78 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt @@ -14,6 +14,7 @@ import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout import android.widget.RelativeLayout import androidx.core.animation.addListener import androidx.core.app.NotificationManagerCompat @@ -28,6 +29,7 @@ import androidx.navigation.Navigation import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.NavHostFragment import com.google.android.material.badge.BadgeDrawable +import com.google.android.material.card.MaterialCardView import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.transition.MaterialSharedAxis import com.tommasoberlose.anotherwidget.R @@ -48,7 +50,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode -class MainFragment : Fragment() { +class MainFragment : Fragment() { companion object { fun newInstance() = MainFragment() @@ -71,21 +73,6 @@ class MainFragment : Fragment() { ): View { viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java) binding = FragmentAppMainBinding.inflate(inflater) - return binding.root - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - - subscribeUi(viewModel) - - if (binding.preview.height == 0) { - binding.preview.layoutParams = binding.preview.layoutParams.apply { - height = PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel( - requireContext() - ) else 0 - } - } // Warnings if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) { @@ -125,6 +112,10 @@ class MainFragment : Fragment() { requireContext() ) else 0 } + + subscribeUi(viewModel) + + return binding.root } private fun subscribeUi(viewModel: MainViewModel) { @@ -171,6 +162,10 @@ class MainFragment : Fragment() { binding.toolbar.cardElevation = if (it > 0) 24f else 0f } + viewModel.showPreview.observe(viewLifecycleOwner) { + updatePreviewVisibility() + } + viewModel.clockPreferencesUpdate.observe(viewLifecycleOwner) { updateClock() } @@ -236,10 +231,6 @@ class MainFragment : Fragment() { } } } - } else { - binding.preview.layoutParams = binding.preview.layoutParams.apply { - height = 0 - } } } @@ -270,28 +261,57 @@ class MainFragment : Fragment() { } private fun updateClockVisibility(showClock: Boolean) { - binding.preview.animation?.cancel() + binding.widgetDetail.timeContainer.clearAnimation() + binding.widgetDetail.time.clearAnimation() - val clockInitialHeight = binding.widgetDetail.timeContainer.measuredHeight.toFloat() - ValueAnimator.ofFloat( - if (Preferences.showClock) 0f else 1f, - if (Preferences.showClock) 1f else 0f - ).apply { - this.duration = 500L - addUpdateListener { - val animatedValue = animatedValue as Float + updatePreviewVisibility() - binding.preview.layoutParams = binding.preview.layoutParams.apply { - height = (PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + 100.toPixel(requireContext()) * animatedValue).toInt() - } - - binding.widgetDetail.timeContainer.layoutParams = binding.widgetDetail.timeContainer.layoutParams.apply { - height = (clockInitialHeight * animatedValue).toInt() - } - binding.widgetDetail.timeContainer.translationY = (clockInitialHeight * animatedValue - clockInitialHeight) - binding.widgetDetail.timeContainer.alpha = animatedValue + if (showClock) { + binding.widgetDetail.timeContainer.layoutParams = binding.widgetDetail.timeContainer.layoutParams.apply { + height = RelativeLayout.LayoutParams.WRAP_CONTENT } - }.start() + binding.widgetDetail.timeContainer.measure(0, 0) + } + + if ((Preferences.showClock && binding.widgetDetail.time.alpha != 1f) || (!Preferences.showClock && binding.widgetDetail.time.alpha != 0f)) { + val initialHeight = binding.widgetDetail.timeContainer.measuredHeight + ValueAnimator.ofFloat( + if (showClock) 0f else 1f, + if (showClock) 1f else 0f + ).apply { + duration = 300L + addUpdateListener { + val animatedValue = animatedValue as Float + binding.widgetDetail.timeContainer.layoutParams = + binding.widgetDetail.timeContainer.layoutParams.apply { + height = (initialHeight * animatedValue).toInt() + } + binding.widgetDetail.time.alpha = animatedValue + } + }.start() + } + } + + private fun updatePreviewVisibility() { + binding.preview.clearAnimation() + if (binding.preview.layoutParams.height != (if (Preferences.showPreview) PREVIEW_BASE_HEIGHT.toPixel(requireContext()) else 0) + (if (Preferences.showClock) 100.toPixel( + requireContext() + ) else 0)) { + ValueAnimator.ofInt( + binding.preview.height, + (if (Preferences.showPreview) PREVIEW_BASE_HEIGHT.toPixel(requireContext()) else 0) + (if (Preferences.showClock) 100.toPixel( + requireContext() + ) else 0) + ).apply { + duration = 300L + addUpdateListener { + val animatedValue = animatedValue as Int + val layoutParams = binding.preview.layoutParams + layoutParams.height = animatedValue + binding.preview.layoutParams = layoutParams + } + }.start() + } } override fun onResume() { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt index 8e6b253..a7ffa9b 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt @@ -95,7 +95,7 @@ class SettingsFragment : Fragment() { private fun subscribeUi( viewModel: MainViewModel, ) { - viewModel.darkThemePreference.observe(viewLifecycleOwner, Observer { + viewModel.darkThemePreference.observe(viewLifecycleOwner) { AppCompatDelegate.setDefaultNightMode(it) maintainScrollPosition { binding.theme.text = when (it) { @@ -106,29 +106,29 @@ class SettingsFragment : Fragment() { else -> "" } } - }) + } - viewModel.installedIntegrations.observe(viewLifecycleOwner, Observer { + viewModel.installedIntegrations.observe(viewLifecycleOwner) { binding.integrationsCountLabel.text = getString(R.string.label_count_installed_integrations).format( it) - }) + } - viewModel.showPreview.observe(viewLifecycleOwner, Observer { + viewModel.showPreview.observe(viewLifecycleOwner) { maintainScrollPosition { binding.showWidgetPreviewLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) } - }) + } - viewModel.showWallpaper.observe(viewLifecycleOwner, Observer { + viewModel.showWallpaper.observe(viewLifecycleOwner) { maintainScrollPosition { binding.showWallpaperLabel.text = - if (it && activity?.checkGrantedPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == true) getString( + if (it && requireActivity().checkGrantedPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) getString( R.string.settings_visible ) else getString(R.string.settings_not_visible) } - }) + } } private fun setupListener() { @@ -180,19 +180,19 @@ class SettingsFragment : Fragment() { } binding.actionTranslate.setOnClickListener { - activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml") + requireActivity().openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml") } binding.actionWebsite.setOnClickListener { - activity?.openURI("http://tommasoberlose.com/") + requireActivity().openURI("http://tommasoberlose.com/") } binding.actionFeedback.setOnClickListener { - activity?.openURI("https://github.com/tommasoberlose/another-widget/issues") + requireActivity().openURI("https://github.com/tommasoberlose/another-widget/issues") } binding.actionPrivacyPolicy.setOnClickListener { - activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/privacy-policy.md") + requireActivity().openURI("https://github.com/tommasoberlose/another-widget/blob/master/privacy-policy.md") } binding.actionHelpDev.setOnClickListener { @@ -224,6 +224,11 @@ class SettingsFragment : Fragment() { } } + override fun onResume() { + super.onResume() + binding.showWallpaperToggle.setCheckedNoEvent(Preferences.showWallpaper && requireActivity().checkGrantedPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) + } + private fun requirePermission() { Dexter.withContext(requireContext()) .withPermissions( @@ -234,7 +239,7 @@ class SettingsFragment : Fragment() { if (report.areAllPermissionsGranted()) { Preferences.showWallpaper = true } else { - binding.showWallpaperToggle.isChecked = false + binding.showWallpaperToggle.setCheckedNoEvent(false) } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/GlanceTabFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/GlanceTabFragment.kt index 02e5ecd..0650e1c 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/GlanceTabFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/GlanceTabFragment.kt @@ -18,6 +18,7 @@ import android.view.animation.LayoutAnimationController import android.widget.ImageView import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -44,11 +45,11 @@ import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel -import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission -import com.tommasoberlose.anotherwidget.utils.convertDpToPixel -import com.tommasoberlose.anotherwidget.utils.expand -import com.tommasoberlose.anotherwidget.utils.reveal +import com.tommasoberlose.anotherwidget.utils.* +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import net.idik.lib.slimadapter.SlimAdapter @@ -91,6 +92,7 @@ class GlanceTabFragment : Fragment() { // List binding.providersList.hasFixedSize() + binding.providersList.isNestedScrollingEnabled = false val mLayoutManager = LinearLayoutManager(context) binding.providersList.layoutManager = mLayoutManager @@ -172,7 +174,7 @@ class GlanceTabFragment : Fragment() { )) ) View.VISIBLE else View.GONE ) - isVisible = !(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong( + isVisible = (Preferences.showNextAlarm && !AlarmHelper.isAlarmProbablyWrong( requireContext() )) } @@ -343,12 +345,12 @@ class GlanceTabFragment : Fragment() { GlanceProviderHelper.saveGlanceProviderOrder( list ) - adapter.updateData(listOf("header") + list.mapNotNull { + adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById( requireContext(), it ) - } + listOf("footer")) + }) } override fun onChildDraw( @@ -412,15 +414,22 @@ class GlanceTabFragment : Fragment() { viewModel.fragmentScrollY.value = binding.scrollView.scrollY } - adapter.updateData(emptyList()) - lifecycleScope.launchWhenResumed { - delay(800) + lifecycleScope.launch(Dispatchers.IO) { + delay(500) val l = list.mapNotNull { GlanceProviderHelper.getGlanceProviderById( requireContext(), it ) } - adapter.updateData(l) - binding.listContainer.expand() + withContext(Dispatchers.Main) { + binding.loader.animate().scaleX(0f).scaleY(0f).alpha(0f).start() + adapter.updateData(l) + val controller = + AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_fall_down) + + binding.providersList.layoutAnimation = controller + adapter.notifyDataSetChanged() + binding.providersList.scheduleLayoutAnimation() + } } } @@ -495,7 +504,7 @@ class GlanceTabFragment : Fragment() { override fun onResume() { super.onResume() - adapter.notifyItemRangeChanged(1, adapter.data?.size ?: 0) + adapter.notifyItemRangeChanged(0, adapter.data?.size ?: 0) if (dialog != null) { dialog?.show() } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/PreferencesFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/PreferencesFragment.kt index 1aac699..92b89b5 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/PreferencesFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/PreferencesFragment.kt @@ -94,6 +94,14 @@ class PreferencesFragment : Fragment() { viewModel.showWeather.observe(viewLifecycleOwner) { checkWeatherProviderConfig() } + + viewModel.weatherProviderError.observe(viewLifecycleOwner) { + checkWeatherProviderConfig() + } + + viewModel.weatherProviderLocationError.observe(viewLifecycleOwner) { + checkWeatherProviderConfig() + } } private fun setupListener() { @@ -175,18 +183,10 @@ class PreferencesFragment : Fragment() { } private fun checkWeatherProviderConfig() { - if (Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" && !binding.weatherProviderError.isVisible) { - binding.weatherProviderError.expand() - } else { - binding.weatherProviderError.collapse() - } + binding.weatherProviderError.isVisible = Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" binding.weatherProviderError.text = Preferences.weatherProviderError - if (Preferences.showWeather && Preferences.weatherProviderLocationError != "" && !binding.weatherProviderError.isVisible) { - binding.weatherProviderLocationError.expand() - } else { - binding.weatherProviderLocationError.collapse() - } + binding.weatherProviderLocationError.isVisible = Preferences.showWeather && Preferences.weatherProviderLocationError != "" binding.weatherProviderLocationError.text = Preferences.weatherProviderLocationError } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt index 0f73137..a3eadeb 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/tabs/WeatherFragment.kt @@ -149,18 +149,10 @@ class WeatherFragment : Fragment() { } private fun checkWeatherProviderConfig() { - if (Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" && !binding.locationPermissionAlert.isVisible) { - binding.weatherProviderError.expand() - } else { - binding.weatherProviderError.collapse() - } + binding.weatherProviderError.isVisible = Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" binding.weatherProviderError.text = Preferences.weatherProviderError - if (Preferences.showWeather && Preferences.weatherProviderLocationError != "" && !binding.locationPermissionAlert.isVisible) { - binding.weatherProviderLocationError.expand() - } else { - binding.weatherProviderLocationError.collapse() - } + binding.weatherProviderLocationError.isVisible = Preferences.showWeather && Preferences.weatherProviderLocationError != "" binding.weatherProviderLocationError.text = Preferences.weatherProviderLocationError } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt index 3e18e71..1b5792f 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/viewmodels/MainViewModel.kt @@ -154,9 +154,6 @@ class MainViewModel(context: Application) : AndroidViewModel(context) { addSource(Preferences.asLiveData(Preferences::customLocationLon)) { value = true } addSource(Preferences.asLiveData(Preferences::customLocationAdd)) { value = true } - addSource(Preferences.asLiveData(Preferences::showPreview)) { value = true } - - addSource(Preferences.asLiveData(Preferences::enabledGlanceProviderOrder)) { value = true } addSource(Preferences.asLiveData(Preferences::customNotes)) { value = true } addSource(Preferences.asLiveData(Preferences::showNextAlarm)) { value = true } diff --git a/app/src/main/res/layout/fragment_preferences.xml b/app/src/main/res/layout/fragment_preferences.xml index 72e10c7..d5784c2 100644 --- a/app/src/main/res/layout/fragment_preferences.xml +++ b/app/src/main/res/layout/fragment_preferences.xml @@ -275,28 +275,28 @@ android:layout_height="wrap_content" android:duplicateParentState="true" android:textSize="14sp" - android:paddingStart="64dp" - android:paddingEnd="16dp" - android:paddingBottom="8dp" android:visibility="gone" android:id="@+id/weather_provider_error" android:textColor="@color/errorColorText" android:letterSpacing="0" + android:paddingTop="8dp" android:fontFamily="@font/google_sans_bold" android:textStyle="bold" + android:text="@string/weather_provider_error_missing_key" android:textAppearance="@style/TextAppearance.MaterialComponents.Button" app:textAllCaps="false" /> diff --git a/app/src/main/res/layout/fragment_tab_glance.xml b/app/src/main/res/layout/fragment_tab_glance.xml index 16957c5..091b01a 100644 --- a/app/src/main/res/layout/fragment_tab_glance.xml +++ b/app/src/main/res/layout/fragment_tab_glance.xml @@ -43,22 +43,34 @@ android:text="@string/settings_sort_glance_providers_subtitle" android:textAppearance="@style/AnotherWidget.Settings.SubHeader"/> - - + + - + android:layout_height="wrap_content" + android:id="@+id/list_container"> + + +