PedroBern / react-native-collapsible-tab-view

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

How to keep header when change tab? #329

Open phuocantd opened 1 year ago

phuocantd commented 1 year ago

When I change tab like video, it will move the header up and down

Version "react": "18.2.0", "react-native": "^0.70.6", "react-native-collapsible-tab-view": "^5.0.0-rc.13", "react-native-pager-view": "^6.1.2",

https://user-images.githubusercontent.com/31690470/228413590-fab31cc3-ddc0-4be2-b907-d7781283e4b4.mp4

phuocantd commented 1 year ago

@andreialecu How to fix it? Thanks

Jamal-ReachFirst commented 1 year ago

Facing same issue

andreialecu commented 1 year ago

A repro that can be applied on the Example app in this repository would help.

lchenfox commented 1 year ago

The same issue. For me, the header for Tabs.FlatList scrolls to top automatically when the tab is clicked. How to fix it please? @andreialecu

andreialecu commented 1 year ago

Which version of the library? Can you reproduce this in the Example app in the repository?

lchenfox commented 1 year ago

@andreialecu Thank you for your quick reply. The problem I figured out is that I called jumpToTab() to the same active tab. It looks like:

const tabRef = useRef(null);
const [activeTabName, setActiveTabName] = useState("FirstTab");

return (
    <View style={{ flex: 1, backgroundColor: 'white' }}>
        <ScrollView contentContainerStyle={{ flexGrow: 1 }} scrollEnabled={false} horizontal={true}>
            <Tabs.Container
                ref={tabRef}
            ...........
            renderTabBar={props => {
                     const {tabNames} = props;
                     return <View style={{flexDirection: 'row'}}>
                     <TouchableOpacity onPress={() => {
                                             // -----------> If you want to control tab event by yourself, you have to add judgment here.
                       if (activeTabName === tabNames[0]) {
                            return;
                       }
                       tabRef.current.jumpToTab(tabNames[0]);
                     }}>
                     <Text>{tabNames[0]}</Text>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => tabRef.current.jumpToTab(tabNames[1])}>
                     <Text>{tabNames[1]}</Text>
                    </TouchableOpacity>
                   </View>;
                }}
            onTabChange={({tabName}) => setActiveTabName(tabName)}
            >
            <Tabs.Tab name={"FirstTab"} label={"label1"}>
                <Tabs.FlatList .../>
            </Tabs.Tab>
            <Tabs.Tab name={"SecondTab"} label={"label2"}>
                <Tabs.FlatList .../>
            </Tabs.Tab>
        </Tabs.Container>
      </ScrollView>
   </View>
);

In a nutshell, just returns if the current tab is focused(active) and it's clicked again.

const goToTab = name => {
         // Condition here, if not, the header will scroll up to top automatically if you jump to the current tab focused!
    if (name === activeTab) {
        return;
    }
    // Jump to any tab you want here!
};
dannykennedy commented 1 year ago

I'm having the same issue. It's hard to reproduce reliably, but I think it might have to do with changing tabs while a Tabs.FlatList is still rendering. I can do the same set of actions quickly and slowly, and fairly reliably the slow version works smoothly and the quick version janks the page around. This is using version 6.1.4, and a flatlist of 28 medium-complicated components (feed items). The feed items are making some API calls, but nothing that changes their size I believe, the image frame will be the same size whether there's an image there or not and the same thing happens when the feed items have no images.

Fast:

https://github.com/PedroBern/react-native-collapsible-tab-view/assets/14936307/2f3a4a7d-e75a-411b-9a89-90db015b10f5

Slow:

https://github.com/PedroBern/react-native-collapsible-tab-view/assets/14936307/af5957d2-0f65-45a0-9b42-1d77952599af

The basic code:

import React from 'react'
import { useColorModeValue } from 'native-base'
import {
  Tabs,
  MaterialTabBar,
  TabBarProps,
  TabProps,
} from 'react-native-collapsible-tab-view'

const tabBar = (props: TabBarProps) => {
  return (
    <MaterialTabBar
      {...props}
      indicatorStyle={{
        backgroundColor: useColorModeValue('#000000', '#ffffff'),
      }}
      labelStyle={{
        fontFamily: 'FavoritTrialStd-Light',
        fontSize: 14,
      }}
      tabStyle={{
        backgroundColor: useColorModeValue('#ffffff', '#000000'),
      }}
      activeColor={useColorModeValue('#000000', '#ffffff')}
      inactiveColor={useColorModeValue('#333333', '#dddddd')}
    />
  )
}

type TabViewProps = {
  header?: () => JSX.Element
  tabs: TabProps<string>[]
}

export const TabView = ({ header, tabs }: TabViewProps) => {
  return (
    <Tabs.Container
      renderHeader={header}
      renderTabBar={tabBar}
      allowHeaderOverscroll={true}
    >
      {tabs.map((tab) => (
        <Tabs.Tab name={tab.name} key={tab.name}>
          {tab.children}
        </Tabs.Tab>
      ))}
    </Tabs.Container>
  )
}
GhayoorUlHaq commented 8 months ago

Facing the same issue, I reproduced from example directory. @dannykennedy I tried slow and quickly and don't think its related, its happening anyways.

https://github.com/PedroBern/react-native-collapsible-tab-view/assets/29123342/a14c9a99-237c-4782-9070-800fdec1a2d3

GhayoorUlHaq commented 8 months ago

Not only scrollable tabs, I'm also having same issue with custom tabbar in my project.

@andreialecu any work around to fix this?