adding automatic rotation of the onboarding carousel items

- items change every 5 seconds
- uses fake dragging to control the page transition speed, by default it's too fast
This commit is contained in:
Adam Brown 2021-12-16 15:20:20 +00:00
parent 28f6d10af9
commit fa30691583
3 changed files with 94 additions and 1 deletions

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.extensions
fun Int.incrementAndWrap(max: Int, min: Int = 0, amount: Int = 1) = if (this == max) min else this + amount

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.extensions
import android.animation.Animator
import android.animation.TimeInterpolator
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.viewpager2.widget.ViewPager2
fun ViewPager2.setCurrentItem(
item: Int,
duration: Long,
interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(),
pagePxWidth: Int = width // Default value taken from getWidth() from ViewPager2 view
) {
val pxToDrag: Int = pagePxWidth * (item - currentItem)
val animator = ValueAnimator.ofInt(0, pxToDrag)
var previousValue = 0
animator.addUpdateListener { valueAnimator ->
val currentValue = valueAnimator.animatedValue as Int
val currentPxToDrag = (currentValue - previousValue).toFloat()
kotlin.runCatching {
fakeDragBy(-currentPxToDrag)
previousValue = currentValue
}.onFailure { animator.cancel() }
}
animator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator?) {
beginFakeDrag()
}
override fun onAnimationEnd(animation: Animator?) {
endFakeDrag()
}
override fun onAnimationCancel(animation: Animator?) = Unit
override fun onAnimationRepeat(animation: Animator?) = Unit
})
animator.interpolator = interpolator
animator.duration = duration
animator.start()
}

View File

@ -22,20 +22,29 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import im.vector.app.BuildConfig import im.vector.app.BuildConfig
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.incrementAndWrap
import im.vector.app.core.extensions.setCurrentItem
import im.vector.app.core.flow.tickerFlow
import im.vector.app.databinding.FragmentFtueSplashCarouselBinding import im.vector.app.databinding.FragmentFtueSplashCarouselBinding
import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures
import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingAction
import im.vector.app.features.onboarding.OnboardingFlow import im.vector.app.features.onboarding.OnboardingFlow
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.Failure
import java.net.UnknownHostException import java.net.UnknownHostException
import javax.inject.Inject import javax.inject.Inject
private const val CAROUSEL_ROTATION_DELAY_MS = 5000L
private const val CAROUSEL_TRANSITION_TIME_MS = 500L
class FtueAuthSplashCarouselFragment @Inject constructor( class FtueAuthSplashCarouselFragment @Inject constructor(
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val vectorFeatures: VectorFeatures, private val vectorFeatures: VectorFeatures,
@ -52,7 +61,8 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
} }
private fun setupViews() { private fun setupViews() {
views.splashCarousel.adapter = carouselController.adapter val carouselAdapter = carouselController.adapter
views.splashCarousel.adapter = carouselAdapter
TabLayoutMediator(views.carouselIndicator, views.splashCarousel) { _, _ -> }.attach() TabLayoutMediator(views.carouselIndicator, views.splashCarousel) { _, _ -> }.attach()
carouselController.setData(SplashCarouselState()) carouselController.setData(SplashCarouselState())
@ -69,6 +79,13 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
"Branch: ${BuildConfig.GIT_BRANCH_NAME}" "Branch: ${BuildConfig.GIT_BRANCH_NAME}"
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) } views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
} }
views.splashCarousel.apply {
val itemCount = carouselAdapter.itemCount
tickerFlow(lifecycleScope, delayMillis = CAROUSEL_ROTATION_DELAY_MS)
.onEach { setCurrentItem(currentItem.incrementAndWrap(max = itemCount - 1), duration = CAROUSEL_TRANSITION_TIME_MS) }
.launchIn(lifecycleScope)
}
} }
private fun getStarted() { private fun getStarted() {