jeongshin / react-native-awesome-swiper

Swiper UI Library for React Native 🙇🏻‍♂️
https://docs.react-native-awesome-swiper.site
3 stars 0 forks source link

Feature Request: Update index on scroll #7

Open elitenas opened 1 year ago

elitenas commented 1 year ago

I would like a delegate that gives me back the index we scrolled to once the scroll ends so I can update my current index state variable.

Currently, I update the currentIndex on button press which works fine but when the user swipes right or left on the list, the index doesn't update because there is not delegate or callback for it.

My code below:

<DynamicItemScrollSwiper
        horizontal
       data={data}
        viewOffset={0}
       gap={10}
       snapToInterval={PAGE_WIDTH}
       decelerationRate="fast"
       renderItem={renderPrayerTimesList}
       activeIndex={currentIndex}
/>
jeongshin commented 1 year ago

Can you give me more brief explanation? I don't get

but when the user swipes right or left on the list, the index doesn't update

you have two lists and trying to sync activeIndex? or you just want to track index of currently visible item

Screen recording might be very helpful for my understanding!

elitenas commented 1 year ago

Demo (Please use IOS): https://snack.expo.dev/@muslimplusapp/react-native-awesome-carousel

In the demo if you press the next button, currentIndex updates fine.

However, if you drag the cards right and left with your mouse, the currentIndex doesn't update. I am looking for a callback that i can use that can help me set currentIndex

If you would still like a video, I can provide that as well

jeongshin commented 1 year ago

DynamicItemScrollSwiper uses ScrollView for known size of items. So tracking currently centered item in screen is more ambiguous when its size is dynamic.

Fixed size of items (PAGE_WIDTH) and tracking centered item is not spec of DynamicItemScrollSwiper.

FYI, I'm planning to make component with fixed size items with headers like TabView or TabSwiper and there might be spec you suggested.

I can't tell you exact release date because I'm quite busy working on my side projects at this moment 🥲. I'll do it before everything else in this project when I have time.

Thank you!

elitenas commented 1 year ago

Why does this component use scrollview instead of flatlist? Would this more possible with a flatlist approach? Isn't flatlist more optimized?

jeongshin commented 1 year ago

DynamicItemScrollSwiper automatically scrolls to given index as activeIndex. So it requires knowing all items' layout to calculate offset of activeIndex item.

If it uses FlatList, it should set initialNumToRender same as length of data. Which means it might not have a big performance difference. If you can memoize component that used to renderItem, it might not have performance bottleneck.

Fyi, I'm currently working on PageSwiper to render each pages for headers using FlatList. Rendering pages should consider performance issues by using windowSize, initialNumToRender, etc.. FlatList performance

https://github.com/jeongshin/react-native-awesome-swiper/assets/64301935/700abb9b-5828-499e-8642-154010797118

For PageSwiper, my initial plan was including shared headers spec, but I could not find a way to remove those blank area. So next release might not include shared header spec.

https://github.com/jeongshin/react-native-awesome-swiper/assets/64301935/d8ee959b-aa76-4588-8596-a09b56467d26

elitenas commented 1 year ago

This is a great idea. However, we have a custom header which this will probably not work for us. We have a next and previous day button that we use to scroll through the list automatically. The only issue we are stuck on is when the user doesn't use those buttons and just swipers manually... how do we update the currentIndex

jeongshin commented 1 year ago

Do your items have fixed size or dynamic size?

elitenas commented 1 year ago

Fixed size

jeongshin commented 1 year ago

If size exactly fits screen width you might can use upcoming PageSwiper which has onActivePageIndexChange props for tracking currently active page index.

interface PageSwiperProps<T>
  extends Omit<
      Partial<FlatListProps<T>>,
      | 'data'
      | 'renderItem'
      | 'viewabilityConfig'
      | 'getItemLayout'
      | 'snapToInterval'
    >,
    ViewabilityConfig {
  pages: T[];
  onActivePageIndexChange?: (index: number) => void;
}

I'm currently done with v1 spec implement, but still have documentation todo. And I can't tell you it's 100% production ready .. 🥲

There's still alternatives like react-native-pager-view

elitenas commented 1 year ago

onActivePageIndexChange is exactly what I need. Can you use PageSwiper without header?

jeongshin commented 1 year ago

yes you can use it without header please check updated v0.3.0 docs I hope this update can help you!

elitenas commented 1 year ago

We are getting this error:

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <PrayerTimesList />. Did you accidentally export a JSX literal instead of a component?

_pages.push({ label: 'test', Component: <TimesList key={item.format('YYYY-MM-DD HH:mm:ss')} currentDay={item}/> });

Can the component just use the regular FlatList prop renderItem?

jeongshin commented 1 year ago

I released fixed version for when JSX Element Component given. And it will look for given renderItem first then use internal renderItem please check v0.3.2 thanks.