Последняя страница HorizontalPager особенно липкая [закрыто]Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Последняя страница HorizontalPager особенно липкая [закрыто]

Сообщение Anonymous »

В настоящее время я работаю над HorizontalPager (сочинением), который демонстрирует особую «липкость» последней страницы. Прокрутка от последней страницы (назад к предпоследней) сложнее и требует значительно более быстрого или дальнего пролистывания. Если только (!) я не выполню смахивание по самому правому краю дисплея. Труднее определить это, потому что этот эффект особенно заметен на определенных устройствах (например, Pixel 9 Pro) по сравнению с другими.
Желаемое поведение должно заключаться в том, чтобы каждую страницу было одинаково сложно/легко прокручивать/пролистывать. Но на самом деле последнюю страницу всегда труднее прокрутить.
Вот как я создаю пейджер:

Код: Выделить всё

OnboardingPager(
snackHostState = snackState,
navHostController = navController,
pagerVisible = pagerVisible,
notificationSettingsUseCases = viewModel.notificationSettingsUseCases,
profileSettingsUseCases = viewModel.profileSettingsUseCases
)

@Composable
fun OnboardingPager(
snackHostState: SnackbarHostState,
navHostController: NavHostController,
pagerVisible: MutableState,
notificationSettingsUseCases: NotificationSettingsUseCases,
profileSettingsUseCases: ProfileSettingsUseCases
) {
val pages = remember { OnboardingPages.entries }
val startPage = remember { 0 }
val pagerState = rememberPagerState(initialPage = startPage) { pages.size }
val pageDone = remember { mutableStateOf(null) }

AnimatedVisibility(
visible = pagerVisible.value,
modifier = Modifier.fillMaxSize(),
enter = fadeIn() + scaleIn(initialScale = .5f),
exit = scaleOut(targetScale = .5f) + fadeOut(),
) {
Column {
ControlledHorizontalPager(
pagerVisible = pagerVisible,
pagerState = pagerState,
pageDone = pageDone,
modifier = Modifier
.fillMaxWidth()
.weight(.9f),
snackState = snackHostState,
navController = navHostController,
onLastPageDone = { profileSettingsUseCases.setOnboardingCompleteUseCase() }
) { pageNumber ->
when(val page = OnboardingPages.entries[pageNumber]) {
INTRODUCTION ->
PageIntroduction(
page = page,
pagerState = pagerState,
setPageDone = { pageDone.value = it }
)
PROFILE ->
PageProfile(
page = page,
pagerState = pagerState,
setPageDone = { pageDone.value = it },
profileSettingsUseCases = profileSettingsUseCases
)

NOTIFICATIONS ->
PageNotifications(
page = page,
pagerState = pagerState,
setPageDone = { pageDone.value = it },
notificationSettingsUseCases = notificationSettingsUseCases
)
}
}
AnimatedPagerDots(
count = pages.size,
pagerState = pagerState,
modifier = Modifier
.fillMaxWidth()
.weight(.1f)
.padding(bottom = 24.dp)
)
}
}
}

@Composable
fun ControlledHorizontalPager(
pagerVisible: MutableState,
pagerState: PagerState,
pageDone: MutableState,
modifier: Modifier = Modifier,
snackState: SnackbarHostState,
navController: NavHostController,
onLastPageDone: () -> Unit,
pageContent: @Composable PagerScope.(page: Int) -> Unit
) {
//-1 for no pages are done yet
fun isForwardScrollProhibited() = pagerState.currentPage > (pageDone.value?.ordinal ?: -1)
var swipeHintPresented by remember { mutableStateOf(false) }

HorizontalPager(
state = pagerState,
modifier = modifier
.pointerInput(Unit) {
awaitEachGesture {
do {
val event: PointerEvent = awaitPointerEvent(
pass = PointerEventPass.Initial
)
event.changes.forEach {
val diffX = it.position.x - it.previousPosition.x
if (diffX < 0 &&  isForwardScrollProhibited()) {
it.consume()
}
}
} while (event.changes.any { it.pressed })
}
}
,
pageContent = pageContent,
)

LaunchedEffect(pageDone.value) {
Timber.d("LaunchedEffect pageDone.value ${pageDone.value}")
val pdv = pageDone.value
if (pdv != null) {
if (!pdv.isLastPage()) {
pagerState.animateScrollToPage(
page = pagerState.currentPage + 1,
animationSpec = PagerScrollAnimationSpec.slowDownScrollAnimationSpec())
if (pdv.isFirstPage() && !swipeHintPresented) {
snackState.showSnackbar(
message = "Wischen zum Zurückgehen",
actionLabel = "OK",
duration = SnackbarDuration.Long
)
swipeHintPresented = true
}
} else {
pagerVisible.value = false
onLastPageDone()

navController.navigate(Destinations.Home.route) {
popUpTo(Destinations.Onboarding.route) {
inclusive = true
}
}
}
}
}
}
ControlledHorizontalPager гарантирует, что пользователь не сможет прокрутить страницу регистрации, которая еще не была завершена. Поэтому он захватывает/использует любую прокрутку вперед на последней странице.
НО: я уже пробовал без использования жестов. Результат тот же.
Это меня сбивает с толку. Есть идеи, в чем может быть причина?
РЕДАКТИРОВАТЬ: Ранее я пытался закомментировать .pointerInput(Unit) { из модификатора HorizontalPager, и это не помогло. Теперь, когда я это комментирую, проблема исчезла. Там что-то застряло. Похоже, проблема решена.
Похоже, что добавление дополнительных страниц программным способом по мере прохождения пользователем адаптации было бы лучшим решением. Тогда на последней странице правильно отображается эффект чрезмерной прокрутки при попытке прокрутить неполную страницу.

Подробнее здесь: https://stackoverflow.com/questions/798 ... rly-sticky
Ответить

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

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

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

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

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