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:
parent
28f6d10af9
commit
fa30691583
|
@ -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
|
|
@ -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()
|
||||
}
|
|
@ -22,20 +22,29 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.airbnb.mvrx.withState
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import im.vector.app.BuildConfig
|
||||
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.features.VectorFeatures
|
||||
import im.vector.app.features.onboarding.OnboardingAction
|
||||
import im.vector.app.features.onboarding.OnboardingFlow
|
||||
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 java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val CAROUSEL_ROTATION_DELAY_MS = 5000L
|
||||
private const val CAROUSEL_TRANSITION_TIME_MS = 500L
|
||||
|
||||
class FtueAuthSplashCarouselFragment @Inject constructor(
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val vectorFeatures: VectorFeatures,
|
||||
|
@ -52,7 +61,8 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun setupViews() {
|
||||
views.splashCarousel.adapter = carouselController.adapter
|
||||
val carouselAdapter = carouselController.adapter
|
||||
views.splashCarousel.adapter = carouselAdapter
|
||||
TabLayoutMediator(views.carouselIndicator, views.splashCarousel) { _, _ -> }.attach()
|
||||
carouselController.setData(SplashCarouselState())
|
||||
|
||||
|
@ -69,6 +79,13 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
|||
"Branch: ${BuildConfig.GIT_BRANCH_NAME}"
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue