PedroBern / react-native-collapsible-tab-view

A cross-platform Collapsible Tab View component for React Native
MIT License
815 stars 161 forks source link

Is there some simple guide to using this library? #330

Closed bpeck81 closed 1 year ago

bpeck81 commented 1 year ago

I don't have any experience with Reanimated, though it seems that it's a requirement to use this library. I'm trying to do some simple things, like change the text size in the tabs, but the code looks pretty intricate to just make a small change. Is there a simple guide to using this?

andreialecu commented 1 year ago

Try looking at the example and running it locally.

You only need to know how to use Reanimated if you're doing more advanced things.

bpeck81 commented 1 year ago

I appreciate your work, but wouldn't it be better to make an easy to use guide as part of your documentation...? Or do you really want people to comb through your example code?

bpeck81 commented 1 year ago

I am unable to setup your example app locally.

Screenshot 2023-04-12 at 3 17 42 PM
andreialecu commented 1 year ago

I appreciate your work, but wouldn't it be better to make an easy to use guide as part of your documentation...? Or do you really want people to comb through your example code?

Please feel free to improve this, PRs appreciated. 🙏

I am unable to setup your example app locally.

You cannot use Expo Go, you'll need to create a native development build. Try yarn ios or yarn android in the example directory.

bpeck81 commented 1 year ago
Screenshot 2023-04-12 at 3 57 09 PM

I am reaching this error.

bpeck81 commented 1 year ago

Okay I played around with this library for a while and it turns out it was not user error, but the library has issues. I'll share what worked for me to save others time.

  1. The library example doesn't work because the author hasn't updated it to the latest SDK.
  2. The View that come before the collapsible header needs to have style={{zIndex:0, backgroundColor:'MyColor'}}
  3. You may need to experiment with background colors and set them explicitly rather than leaving them as default transparent..
  4. The animated header example isn't useful. What worked for me was structuring my header component like this: {your header content}</Animated.View>
  5. Your header isn't supposed to have touchable opacities in it. If it does, you'll have to deal with pointer events.
  6. You can't scroll the header and have touchables in it. That's a big problem for most people!

But... I found an obscure comment here which provides idea around an alternative to this library. It works with a scrollable header and touchables in the header, but has some drawbacks. The main feature it doesn't have is the tab bar doesn't stick to the top and just scrolls out of the view (which is a perfectly fine tradeoff for me).

If you use a specific version of react native tab view you can literally just use a scrollview with your header. It will not work with the current version.

Use this: yarn add react-native-tab-view@2.16.0

My code ended up looking super simple:

import { TabBar, TabView } from 'react-native-tab-view'

const MyComponent = ()=>{

const [index, setIndex] = useState(0)
return(
<View style={{ flex: 1 }}>
<MyPermanentTopHeader />
<ScrollView>
    <MyCollapsibleHeader />
    <TabView
        navigationState={{ index, routes: [{ key: 'tab1', title: 'tab2' }, { key: 'tab1', title: 'tab2' }] }}
        renderScene={({ route }) => {
            switch (route.key) {
                case 'tab1':
                    return <FlatList (with all my data) />
                case 'tab2':
                    return <FlatList (with all my data ) />
                default:
                    return null;
            }
        }}
        onIndexChange={setIndex}
        renderTabBar={props => <TabBar
            {...props}
            renderLabel={({ route }) => (
                <Text style={{MyStyling}}>
                    {route.title}
                </Text>
            )}
            indicatorStyle={{ backgroundColor: 'blue' }}
            style={{ backgroundColor: 'white' }}
        />}
    />
</ScrollView>
</View>
)
bpeck81 commented 1 year ago

@PedroBern I tried this library but like yours better. The one linked has scrolling performance issues and unnecessary animations I don't know how to remove. I can generally make yours work but the main feature yours is missing which this has is that you can press items in the collapsible header. Is there any way you would be willing to implement that feature? What would it take for you to do that?

andreialecu commented 1 year ago

You can press items in the header. There's an example that shows that. It's not perfect, however and has some limitations. It has been discussed several times in the issues in this repository.

Implementing it properly is currently not possible due to upstream limitations. See: https://github.com/software-mansion/react-native-gesture-handler/discussions/2033#discussioncomment-2747981

bpeck81 commented 1 year ago

@andreialecu
My fault, I meant be able to press buttons and scroll on the header. My app has a very large header, so it requires scrolling unfortunately. I've been stuck on this problem for almost a week. Modifying pointerEvents doesn't seem to work well, so I can't scroll unless I change my header pointerEvents 'none'.

So there's no way to fix this? For what it's worth, the library I shared above has this feature working. I can also scroll over a header, press its buttons, and switch tabs with the code I shared above, but there are issues with it: the tabbar doesn't stick to the top, swiping to switch views causes the list swiped from to be pressed, and the list lengths are not changed when you switch views.

bpeck81 commented 1 year ago

Adding on to my example above, I've found a way to give it all required functionality except swiping between screens. So it's a tradeoff to have a scrollable and pressable collapsible header instead of swiping between screens, which is a tradeoff I need to make for my app. As a side effect, I notice that this method also has the screens better adapt to the size of the lists in each page and better image scrolling performance.

const [index, setIndex] = useState(0)
return(
<View style={{ flex: 1 }}>
<MyPermanentTopHeader />
<ScrollView
          showsVerticalScrollIndicator={false}
          stickyHeaderIndices={[1]}
>
    <MyCollapsibleHeader />
    <TabView
        navigationState={{ index, routes: [{ key: 'tab1', title: 'tab2' }, { key: 'tab1', title: 'tab2' }] }}
        renderScene={({ route }) => {
            switch (route.key) {
                case 'tab1':
                           break;
                case 'tab2':
                           break;
                default:
                    return null;
            }
        }}
        onIndexChange={setIndex}
        renderTabBar={props => <TabBar
            {...props}
            renderLabel={({ route }) => (
                <Text style={{MyStyling}}>
                    {route.title}
                </Text>
            )}
            indicatorStyle={{ backgroundColor: 'blue' }}
            style={{ backgroundColor: 'white' }}
        />}
    />
      {index == 0 ? (
                <FlatList (my first list).... />
      ) : (
                <FlatList (my second list).... />
      )}
</ScrollView>
</View>
)
senghuotlay commented 9 months ago

@bpeck81 for some reason why i follow your solution, i am unable to scrolldown to my flatlist :(

coofzilla commented 2 months ago

I appreciate your work, but wouldn't it be better to make an easy to use guide as part of your documentation...? Or do you really want people to comb through your example code?

I had a similar issue; however, after just cloning and building it, the example app is actually awesome. Its not as convenient as typical documentation; but, its really really good.