Как получить индекс активного видимого элемента в ленивой строке в Jetpack Compose?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как получить индекс активного видимого элемента в ленивой строке в Jetpack Compose?

Сообщение Anonymous »


I try to create carousel with fling behavior in lazy row. And I want to change background of canvas rectangle according to scroll index. But no matter I try always see weird behavior of index value when I scroll.

My code:

@OptIn(ExperimentalFoundationApi::class) @Composable fun HeroCards( list: List, onCardClick: (heroImageUrlArg: String, heroNameIdArg: Int, heroDescIdArg: Int) -> Unit, ) { val state = rememberForeverLazyListState(key = "Overview") val snappingLayout = remember(state) { SnapLayoutInfoProvider(state) } val flingBehavior = rememberSnapFlingBehavior(snappingLayout) var activeIndex by remember { mutableIntStateOf(0) } state.firstVisibleItemIndex val backgroundColors = remember { mapOf( 0 to Color(0xFF00FF99), 1 to Color(0xFF0004FF), 2 to Color(0xFFDB2222) ) } val nestedScrollConnection = remember { object : NestedScrollConnection { override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { if (activeIndex == 2) { activeIndex = 0 } else { activeIndex += 1 } return Velocity.Zero } } } BoxWithConstraints( modifier = Modifier .fillMaxSize() .drawBehind { withTransform({ translate(left = size.width / 1.7f) rotate(degrees = 40f) }) { drawRect( color = backgroundColors[activeIndex] ?: Color.Transparent, topLeft = Offset( x = size.width / 6f, y = size.height / 3F ), size = size ) } } ) { LazyRow( modifier = Modifier.nestedScroll(nestedScrollConnection), state = state, flingBehavior = flingBehavior, ) { itemsIndexed(list) { index, hero -> Layout( content = { CardItem( state = state, index = list.indexOf(hero), cardText = hero.cardText, cardImageUrl = hero.cardImageUrl, cardDesc = hero.cardDesc, onCardClick = onCardClick ) }, measurePolicy = { measurable, constraints -> val isRtl = layoutDirection == LayoutDirection.Rtl val placeable = measurable.first().measure(constraints) val maxWidthInPx = maxWidth.roundToPx() val itemWidth = placeable.width val startSpace = if (index == list.lastIndex) (maxWidthInPx - itemWidth) / 2 else 0 val endSpace = if (index == 0) (maxWidthInPx - itemWidth) / 2 else 0 val width = startSpace + placeable.width + endSpace layout(width, placeable.height) { val x = when { index == 0 && isRtl -> startSpace index == 0 && !isRtl -> endSpace index == list.lastIndex && isRtl -> startSpace index == list.lastIndex && !isRtl -> width - placeable.width - startSpace else -> 0 } placeable.place(x, 0) } } ) } } } } private val SaveMap = mutableMapOf() private data class KeyParams( val params: String = "", val index: Int, val scrollOffset: Int ) /** * Save scroll state on all time. * @param key value for comparing screen * @param params arguments for find different between equals screen * @param initialFirstVisibleItemIndex see [LazyListState.firstVisibleItemIndex] * @param initialFirstVisibleItemScrollOffset see [LazyListState.firstVisibleItemScrollOffset] */ @Composable fun rememberForeverLazyListState( key: String, params: String = "", initialFirstVisibleItemIndex: Int = 0, initialFirstVisibleItemScrollOffset: Int = 0 ): LazyListState { val scrollState = rememberSaveable(saver = LazyListState.Saver) { var savedValue = SaveMap[key] if (savedValue?.params != params) savedValue = null val savedIndex = savedValue?.index ?: initialFirstVisibleItemIndex val savedOffset = savedValue?.scrollOffset ?: initialFirstVisibleItemScrollOffset LazyListState( savedIndex, savedOffset ) } DisposableEffect(Unit) { onDispose { val lastIndex = scrollState.firstVisibleItemIndex val lastOffset = scrollState.firstVisibleItemScrollOffset SaveMap[key] = KeyParams(params, lastIndex, lastOffset) } } return scrollState } So I tried to use Pager, but it's not have fling behavior and for my task I gotta use it. I tried to use first firstVisibleItemIndex but it seems like weird behavior, I always get kinda random numbers from 0 to 1.

I also tried to use offset, delta logic but it's not help me. In itemsIndexed block, index is also random and weird from 0 to 1. But it should be at least 2 index, which is disappeared.

My carousel looks like this:
Изображение


So I also can't place canvas in Layout because it's not look good. But it work that I want of course, it's change background color. Now I write kind of random code to change background. But it should determine certain background color for certain card index.


Источник: https://stackoverflow.com/questions/780 ... ck-compose
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»