Nesting Horizontal FlatList inside TabView (same orientation) - javascript

I am rendering an horizontal FlatList (from react-native-gesture-handler) inside one of the pages of my top TabView (from react-native-tab-view)
The main problem I am having is that the FlatList scroll "priority" is greater than the TabView's one, so if I want to swipe the top TabView, I have to put the finger outside the FlatList (something which is not really professional).
Here is the FlatList code:
<FlatList
data={data}
renderItem={renderItem}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
style={styles.container}
/>
And the TabView's code:
<TabView
style={styles.tabView}
renderTabBar={renderTabBar}
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={initialLayout}
removeClippedSubviews={false} // Pd: Don't enable this on iOS where this is buggy and views don't re-appear.
swipeEnabled={true}
swipeVelocityImpact={0.2}
gestureHandlerProps={{
activeOffsetX: [-30, 30], // To solve swipe problems on Android
}}
/>
Is there any way to allow the user to swipe the parent component (the TabView) when scrolling the child (the horizontal FlatList)

Have you tried setting scroll enable to false in the FlatList?
https://reactnative.dev/docs/scrollview#scrollenabled

If so, why do you need the flatList component as horizontal scrollable?
Anyway, I found a little tricky solution : wrap entire component result of renderItem of flatList as
<TouchableWithoutFeedback/>.

Related

How can you make a screen with a FlatList scrollable in React Native?

One of my screens has a FlatList, but it also features a TextInput that must remain at the top of the page. The TextInput determines which other component is rendered, if it's empty it is a category page but if it's filled with any text it's the search results. My problem right now is that I have the TextInput outside of the main FlatList, and this causes it to be at the top of the screen even when scrolling the list. I'd like for it to remain at the top of the page and not follow the scroll.
If I put the TextInput inside one of the FlatLists it causes the other to not have it due to rendering separate components. But if I place it in both FlatLists it creates a bug where after typing the first character the TextInput will exit the editing mode since a completely new component is being rendered.
Here's the structure I have right now:
<View>
<TextInput />
<View>
{conditional check ? (
<FlatList /> :
(<View>
<FlatList />
</View>
}
So how docs says FlatList has a props called ListHeaderComponent to display at the top of the list a component. https://reactnative.dev/docs/flatlist
//textinput component
const input = () => {
<View>
<TextInput />
</View>
};
<FlatList
listHeaderComponent={input}
data={/* data or another type of array */}
renderItem={ /* put here what you want to be scrollable */ }
/>
If I understood it correctly that if you want to scroll TextInput with the list, you should wrap the TextInput and all inside ScrollView and instead of using FlatList, map the data to be rendered and pass it to child component like below.
<ScrollView>
<TextInput />
{conditional check ? (
{data1.map((item,index)=> <ChildComponent1/> //renderItem in FlatList 1
)}):
(<View>
{data2.map((item,index)=> <ChildComponent2/> //renderItem in FlatList 2
)}
</View>)
}
<ScrollView>

How can I reveal an element behind a flatlist and have it interactable in React Native?

I am trying to render an element that is positioned absolutely behind a flatlist and it will be revealed once the user scrolls to the bottom. The issue I am facing is that the element needs to be interactable, and the flatlist root element takes all pointerevents instead of the background element.
const FlatlistOverElement: FC = () => (
<View style={{ flex: 1, width: '100%' }}>
<FlatList
data={data}
style={{ flexGrow: 1 }}
ListFooterComponent={() => (
<View style={{ height: BACKGROUND_ELEMENT_HEIGHT, opacity: 0 }} />
)}
renderItem={RenderItem}
/>
<AbsolutelyPositionedElementBehindFlatList />
</View>
)
I have tried to remove pointerevents from the flatlist, then the flatlist is not scrollable.
I have tried to set the height of the flatlist smaller, and let the content overflow. This allows the user to interact with the element, but for that part of the screen, the user can not scroll the flatlist.
What other approach can I utilise in order to solve this issue ?
You can use zIndex property on the scroll completion. Just provide a higher zIndex value than that of FlatList to absolute component whenever the scroll is completed.
zIndex Layout Props
Thanks for the suggestions. I ended up using a zIndex to put the interactable content in front of the flatlist when having scrolled to the end, as well as adding snap points on both sides of the element. To prevent the user from half revealing the element and not be able to interact with it.

How to go to top of the screen with ref react native

how can i go to the top of the screen or other element in the screen with react-native ?
i need to use ref for that ?
note that i have scroll view from outside, so i Cant use scroll view methods
little of my code:
<AnimatedButton
onPress={() => console.log("check", myref.current)}
icon="arrow-up"
/>
)}
and i want to go for example to the first element in the screen:
<View ref={myref}>
<Text style={styles.massagetitle}>בחר סוג טיפול</Text>
</View>
how to handle that without scrollView ?? (again, because i cant put scroll view because i have scroll view from outside wrap it)

React Native ScrollView above another ScrollView

I am trying to make something similar to the Instagram ScrollView which is inside the "Search" screen of the app. If you are using iOS and see the app, you will see that when you start typing the username of an user, a ScrollView overlaps the feed ScrollView.
For this I am doing:
<ScrollView>
<HorizontalStoriesList />
...
<Animated.ScrollView
testID="SearchUsersList"
style={[
StyleSheet.absoluteFill,
{
opacity: searchUsersListOpacity,
backgroundColor: colors.white,
},
]}
>
<UsersList data={data} />
</Animated.ScrollView>
</ScrollView>
My problem is that the ScrollView which is more above doesn't have the good height, instead of using its own height it uses the height of the parent scroll view. Also, I am not able to touch the components that are behind this scrollview (The HorizontalStoriesList, for example. I have tried with pointerEvents="none" but this make the Animated Scroll View (the one which is more above) to be untouchable.
Any ideas how to solve this?
Thank you.

React Native: Calling setState in FlatList much slower than setState in ScrollView

I'm rendering a list of contacts, each of which has a clickable icon that triggers a set state. Here's the FlatList version:
<FlatList
data={this.state.contacts}
renderItem={({item, index}) => <Contact
contact={item}
image={this.getImage(item)}
active={item.id in this.state.active}
toggleActive={this.toggleActive} />}
keyExtractor={(item, idx) => idx.toString()}
refreshing={false} />
And here's the ScrollView version:
<ScrollView style={styles.scroll}>
{this.state.contacts.map(c => (
<Contact key={c.id}
contact={c}
image={this.getImage(c)}
active={c.id in this.state.active}
toggleActive={this.toggleActive} />
))}
</ScrollView>
The Contact component and all else remains constant between these two, only the type of scroll container (FlatList vs ScrollView) changes. However, the ScrollView maintains a snappy 60 FPS, while the FlatList drops to ~10 FPS on the JS thread after setState is called. Is this expected behavior, or am I missing something / doing something wrong?
The ScrollView renders the data after it's all loaded, while the flatList loads as you scroll; it loads only what the screen can render thats why you can see blank space if you scroll quickly.
it says in the docs of RN:
In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.

Categories

Resources