NTP-38641 | Pager v2 update (#747)

Co-authored-by: Soumya Ranjan Patra <soumya.ranjan@navi.com>
This commit is contained in:
Venkat Praneeth Reddy
2025-04-28 14:44:46 +05:30
committed by GitHub
parent 8e05d46a17
commit 24ab8eb9e7
5 changed files with 62 additions and 35 deletions

View File

@@ -23,6 +23,7 @@ data class PagerProperty(
var initialPagerPosition: Int? = null,
var isScrollGestureDetectionNeeded: Boolean? = null,
var scrollPageAnimationSpec: AnimationSpec? = null,
var stopScrollAtLastPage: Boolean? = null,
) : BaseProperty() {
companion object {
@@ -47,6 +48,7 @@ data class PagerProperty(
pagerProperty?.initialPagerPosition?.let { initialPagerPosition = it }
pagerProperty?.isScrollGestureDetectionNeeded?.let { isScrollGestureDetectionNeeded = it }
pagerProperty?.scrollPageAnimationSpec?.let { scrollPageAnimationSpec = it }
pagerProperty?.stopScrollAtLastPage?.let { stopScrollAtLastPage = it }
}
data class SpacingStyle(var type: String? = null, var spacing: Int? = null)

View File

@@ -18,9 +18,7 @@ class PagerIndicatorV2ViewRenderer : IUiTronRenderer {
@Composable
override fun RenderUiTronView(uiTronRenderConfig: UiTronRenderConfig) {
(uiTronRenderConfig.composeView.property as? PagerIndicatorProperty)?.let {
PagerIndicatorV2Renderer(
childrenComposeViews = uiTronRenderConfig.composeView.childrenViews.orEmpty()
)
PagerIndicatorV2Renderer()
.Render(
property = it,
uiTronData =

View File

@@ -22,6 +22,11 @@ import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -39,7 +44,6 @@ import com.navi.uitron.model.data.EmptyData
import com.navi.uitron.model.data.UiTronData
import com.navi.uitron.model.ui.PagerIndicatorProperty
import com.navi.uitron.model.ui.UiTronShape
import com.navi.uitron.model.ui.UiTronView
import com.navi.uitron.modifer.ModifierBuilder
import com.navi.uitron.utils.ShapeType
import com.navi.uitron.utils.ShapeUtil
@@ -64,8 +68,7 @@ import com.navi.uitron.viewmodel.UiTronViewModel
import kotlin.math.absoluteValue
import kotlin.math.sign
class PagerIndicatorV2Renderer(private val childrenComposeViews: List<UiTronView>) :
Renderer<PagerIndicatorProperty> {
class PagerIndicatorV2Renderer() : Renderer<PagerIndicatorProperty> {
@Composable
override fun Render(
@@ -76,6 +79,8 @@ class PagerIndicatorV2Renderer(private val childrenComposeViews: List<UiTronView
) {
super.Render(property, uiTronData, uiTronViewModel, modifier)
var updatedData = uiTronData
val initialPagerState = rememberPagerState { 0 }
var pagerState by remember { mutableStateOf(initialPagerState) }
if (property.isStateFul.orFalse()) {
val state =
uiTronViewModel.handle
@@ -91,17 +96,17 @@ class PagerIndicatorV2Renderer(private val childrenComposeViews: List<UiTronView
updatedData = updatedDataState.value ?: updatedData
}
val pagerState =
uiTronViewModel.stateHolder.getOrUpdatePagerV2State(
property.pagerStateKey,
childrenComposeViews.size,
)
property.pagerStateKey?.let { key ->
LaunchedEffect(uiTronViewModel.stateHolder.getPagerStateV2(key)) {
uiTronViewModel.stateHolder.getPagerStateV2(key)?.value?.let { pagerState = it }
}
}
if (property.visible.orTrue() && pagerState?.pageCount.orZero() > 1) {
if (property.visible.orTrue() && pagerState.pageCount.orZero() > 1) {
val rootView = LocalView.current.rootView
if (property.orientation == PagerIndicatorProperty.ORIENTATION_VERTICAL) {
VerticalPagerIndicator(
pagerState = pagerState ?: rememberPagerState { childrenComposeViews.size },
pagerState = pagerState,
modifier =
if (UiTronSdkManager.isModifierBuilderEnabled()) {
ModifierBuilder(
@@ -177,7 +182,7 @@ class PagerIndicatorV2Renderer(private val childrenComposeViews: List<UiTronView
)
} else {
HorizontalPagerIndicator(
pagerState = pagerState ?: rememberPagerState { childrenComposeViews.size },
pagerState = pagerState,
modifier =
if (UiTronSdkManager.isModifierBuilderEnabled()) {
ModifierBuilder(

View File

@@ -10,8 +10,6 @@ package com.navi.uitron.render
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.collectIsDraggedAsState
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.VerticalPager
@@ -19,9 +17,11 @@ import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -61,6 +61,7 @@ import com.navi.uitron.utils.setWidthRange
import com.navi.uitron.viewmodel.UiTronViewModel
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
class PagerRendererV2(
private val childrenComposeViews: List<UiTronView>,
@@ -77,6 +78,8 @@ class PagerRendererV2(
super.Render(property, uiTronData, uiTronViewModel, modifier)
var pagerData = uiTronData as? PagerData
val shouldStopAutoScroll = remember { mutableStateOf(false) }
val initialPagerState = rememberPagerState { childrenComposeViews.size }
val pagerState by remember { mutableStateOf(initialPagerState) }
if (property.isStateFul.orFalse()) {
val state =
uiTronViewModel.handle
@@ -91,13 +94,15 @@ class PagerRendererV2(
.collectAsStateWithLifecycle()
pagerData = updatedDataState.value ?: pagerData
}
property.pagerStateKey?.let { key ->
LaunchedEffect(Unit) {
uiTronViewModel.stateHolder.updatePagerStateV2(key, MutableStateFlow(pagerState))
}
}
if (property.visible.orTrue()) {
val rootView = LocalView.current.rootView
val pagerState =
uiTronViewModel.stateHolder.getOrUpdatePagerV2State(
key = property.pagerStateKey,
pageCount = childrenComposeViews.size,
) ?: rememberPagerState { childrenComposeViews.size }
property.spacingStyle?.let {
interceptChildrenPaddingByStyle(property, childrenComposeViews)
}
@@ -283,6 +288,7 @@ class PagerRendererV2(
property,
uiTronViewModel,
pagerData,
scrollDelay = property.scrollDelay.orZero(),
shouldStopAutoScroll,
)
}
@@ -336,9 +342,9 @@ class PagerRendererV2(
property: PagerProperty,
uiTronViewModel: UiTronViewModel,
pagerData: PagerData?,
scrollDelay: Long,
shouldStopAutoScroll: MutableState<Boolean>,
) {
val updatedStopAutoScrollState = rememberUpdatedState(shouldStopAutoScroll.value)
LaunchedEffect(key1 = pagerState.currentPage) {
snapshotFlow { pagerState.currentPage }
@@ -348,10 +354,10 @@ class PagerRendererV2(
}
val isDraggedState = pagerState.interactionSource.collectIsDraggedAsState()
LaunchedEffect(key1 = isDraggedState.value) {
if (property.scrollDelay.orZero() > 0) {
LaunchedEffect(key1 = isDraggedState.value, key2 = scrollDelay) {
if (scrollDelay > 0) {
while (true) {
delay(property.scrollDelay.orZero())
delay(scrollDelay)
try {
if (updatedStopAutoScrollState.value) {
customLoop@ while (true) {
@@ -363,11 +369,22 @@ class PagerRendererV2(
}
with(pagerState) {
if (!isDraggedState.value && !updatedStopAutoScrollState.value) {
val target = if (currentPage < pageCount - 1) currentPage + 1 else 0
animateScrollToPage(
page = target,
animationSpec = animatedSpec(property.scrollPageAnimationSpec),
)
if (currentPage < pageCount - 1) {
val target = currentPage + 1
animateScrollToPage(
page = target,
animationSpec =
animatedSpec(property.scrollPageAnimationSpec),
)
} else if (property.stopScrollAtLastPage.orFalse()) {
shouldStopAutoScroll.value = true
} else {
animateScrollToPage(
page = 0,
animationSpec =
animatedSpec(property.scrollPageAnimationSpec),
)
}
}
}
} catch (e: CancellationException) {

View File

@@ -11,13 +11,14 @@ import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.pager.PagerState as FoundationPagerState
import androidx.compose.foundation.pager.rememberPagerState as FoundationRememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState as AccompanistPagerState
import com.google.accompanist.pager.rememberPagerState as AccompanistRememberPagerState
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
@OptIn(ExperimentalPagerApi::class)
class ComposeStateHolder @Inject constructor() {
@@ -25,7 +26,8 @@ class ComposeStateHolder @Inject constructor() {
private val pagerStateMap: MutableMap<String, AccompanistPagerState> by lazy { mutableMapOf() }
private val scrollStateMap: MutableMap<String, ScrollState> by lazy { mutableMapOf() }
private val gridStateMap: MutableMap<String, LazyGridState> by lazy { mutableMapOf() }
private val pagerV2StateMap: MutableMap<String, FoundationPagerState> by lazy { mutableMapOf() }
private val pagerV2StateMap:
MutableMap<String, MutableStateFlow<FoundationPagerState>> by lazy { mutableStateMapOf() }
@Composable
fun getOrUpdatePagerState(key: String?): AccompanistPagerState? {
@@ -42,9 +44,12 @@ class ComposeStateHolder @Inject constructor() {
return getOrUpdateState(key, gridStateMap, rememberLazyGridState())
}
@Composable
fun getOrUpdatePagerV2State(key: String?, pageCount: Int): FoundationPagerState? {
return getOrUpdateState(key, pagerV2StateMap, FoundationRememberPagerState { pageCount })
fun updatePagerStateV2(key: String, state: MutableStateFlow<FoundationPagerState>) {
pagerV2StateMap[key] = state
}
fun getPagerStateV2(key: String): MutableStateFlow<FoundationPagerState>? {
return pagerV2StateMap[key]
}
private fun <T> getOrUpdateState(