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)
Related
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>
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.
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/>.
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.
I am looking to build a button/view that animates when a user taps and holds on it. This animation will just be a progressive change of color from white to a green color. I have found a tutorial that does exactly this:
http://browniefed.com/blog/react-native-press-and-hold-button-actions/
In the render function, the author uses:
<View style={styles.container} onLayout={this.onPageLayout}>
<TouchableWithoutFeedback
onPressIn={this.handlePressIn}
onPressOut={this.handlePressOut}
>
<View style={styles.button} onLayout={this.onPageLayout2}>
<Animated.View style={[styles.bgFill, this.getProgressStyles()]} />
<Text style={styles.text}>Press And Hold Me</Text>
</View>
</TouchableWithoutFeedback>
<View>
<Text>{this.state.textComplete}</Text>
</View>
</View>
Please note there are two onLayout mentions...one in the parent View and the other in the View about halfway down
The way this works is the onLayout call is supposed to get the size of the TouchableWithoutFeedback button so that I can set the animation to have the correct sizing. However, the second onLayout call just does not get called no matter what I try. The very top View's onLayout is being called so I know that my code is good (as this.onPageLayout and this.onPageLayout2 are exact copies except their console.logs vary slightly).
If I remove all the surrounding code and only have the inner View in this render function, then the onLayout={this.onPageLayout2} works like a charm, but as soon as I put the rest of the parent back in, it no longer works.
Does anybody know how I can get a child View to have their onLayout method work? Or another way or getting the size of the TouchableWithoutFeedback button for my purposes of animation?
Thanks!
You are using TouchableWithoutFeedback and so you don't get any feedback from it's child. Change it to other buttons for example: TouchableOpacity, Then you can have onLayout for both components.