Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Infinite scroll FlatList flickering #33

Closed
krisnapy opened this issue Jul 28, 2024 · 4 comments
Closed

[BUG] Infinite scroll FlatList flickering #33

krisnapy opened this issue Jul 28, 2024 · 4 comments

Comments

@krisnapy
Copy link

Scroll flickering when using 12 hours format.

import React, { useMemo } from 'react'
import { LinearGradient } from 'react-native-linear-gradient'
import { TimerPickerModal } from 'react-native-timer-picker'

import { theme } from 'theme'

import { TimerPickerModalProps } from './types'

const pickerTheme = {
  theme: 'light' as 'light',
  confirmButton: {
    borderColor: theme.colors.palette.brandPrimary,
  },
  cancelButton: {
    borderColor: theme.colors.palette.greyExtraLight,
  },
}

export const TimePickerModal = (props: TimerPickerModalProps) => {
  const { onCancel, onConfirm, visible, value, modalTitle} = props

  const currentValue = useMemo(() => {
    if (value) {
      return {
        hours: value.getHours(),
        minutes: value.getMinutes(),
        seconds: value.getSeconds(),
      }
    }
    return { hours: 0, minutes: 0, seconds: 0 }
  }, [value])

  const formatTimeToISO = ({
    hours = 0,
    minutes = 0,
    seconds = 0,
  }: {
    hours?: number;
    minutes?: number;
    seconds?: number;
  }) => {
    const date = new Date()
    date.setHours(hours, minutes, seconds)
    return date
  };

  return (
    <TimerPickerModal
      visible={visible}
      setIsVisible={onCancel}
      onConfirm={(pickedDuration) => {
        const dateValue = formatTimeToISO(pickedDuration)
        onConfirm(dateValue)
      }}
      onDurationChange={console.log}
      hideSeconds
      initialValue={currentValue}
      modalTitle={modalTitle}
      onCancel={onCancel}
      closeOnOverlayPress
      use12HourPicker
      LinearGradient={LinearGradient}
      styles={pickerTheme}
    />
  )
}
RPReplay_Final1722179011.MP4
@troberts-28
Copy link
Owner

Hey @krisnapy, thanks for raising this! Will take a look and get this fixed.

@troberts-28
Copy link
Owner

Hey @krisnapy,

I haven't been able to fix this completely but I've made some changes that should help.

The reason you get a flicker is that behind the scenes, each hour/minute/second picker auto-scrolls back up the list when you near the end of the list, to give the appearance of an infinite scroll. Normally the flicker is barely visible, but it's clearly visible if you scroll slowly, as in your video.

It's actually not just confined to the hour picker when using the 12 hour format, but affects all of the pickers. You are less likely to spot it in the minute/second pickers, simply because the list is longer.

Under the hood, the picker repeats the list of numbers a given number of times to avoid auto-scrolling every time you hit the end of the list. Previously, this was hard-coded as 3 repetitions. I have made it possible to configure the number of repititions (with these props: repeatHourNumbersNTimes, repeatMinuteNumbersNTimes and repeatSecondNumbersNTimes) , to reduce the amount of auto-scrolling (and therefore flickering). Bare in mind that there is a slight performance trade-off in increasing those numbers, as the list being rendered increases in length.

I have set the default number of repititions for repeatHourNumbersNTimes to 6, so that the list length mirrors that of the minutes/seconds pickers, and the auto-scroll flickering is less likely to be noticed.

Makes sense?

@troberts-28
Copy link
Owner

I did also improve the auto-scroll function so that it doesn't flick down a number (from 11am to 12pm in your video), instead there is a slight flicker, but it remains on 11am.

@troberts-28
Copy link
Owner

And one more thing!

If you want to avoid the flicker at all costs, you can use disableInfiniteScroll and set the number of repititions to some fairly high value. That will stop any auto-scrolling, but will mean a user can reach the end of the list by scrolling far in either direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants