Sorry if this has been asked previously, but I hadn't found a working answer.
I'm currently working on a simple app. The main screen features a vertical flatlist with user generated content. The header, though, is transparent and has a predefined height, so the user can see a background image; when the flatlist is scrolled, it covers this background image, which remains static. The goal is to give the user the feeling that they're covering this image, similar to the pull-up element on google maps, which covers the map to show more data.
This would be a simplified example of the current, working code, so you get the gist of it:
const HomeComponent = () => (
<View>
<ImageBackground source={require('../assets/background.png')}>
<Flatlist
headerComponent={<TransparentHeaderOfPredefinedHeight/>}
data={DATA}
renderItem={renderItem}
keyExtractor={item => item}/>
</ImageBackground>
</View> )
Up until here, everything is fine. The thing is, I would like to add a touchable button on this background, that is subsequently covered when the Flatlist is scrolled.
Here's the issue. I have no way to make the touch event propagate through the flatlist's header and reach this button. I tried using pointerEvents='none' and 'box-only' in different combinations, but whenever I was able to touch that button, I was in turn unable to scroll or to interact with the flatlist elements.
I also tried pushing the background image and button on the flatlist header, and using the vertical offsite of the flatlist scrolling to move these elements and simulate the flatlist scrolling over it. Unfortunately, the result was absolutely atrocious, lacking any kind of smoothness.
Does anyone know how I could implement this functionality? I can provide more info if needed. Thank you in advance!
Related
I need some help. I've made a custom list view with some animation (drag and drop). everything is working fine except when there is large number of data, its taking too much time to load the page/when navigating back from another page. Is there any technique where I can reduce the page loading time? Please do not suggest any external packages, and also I cannot use flatlist either, due to my Animated.Scrollview conflicting with Flatlist own Scrollview. I've searched online, and everyone is using flatlist, which i cannot use. Or is it possible to ignore FlatList Own ScrollView?
Found an alternate solution here. You can use FlatList for larger data. Then pass your Animated.ScrollView component as a props through FlatList.
renderScrollComponent={(props) => (
<Animated.ScrollView
{...props}
onScroll={(event) => {
onScroll({ y: feedScroll })(event)
props.onScroll(event)
}}
/>
)}
Main technologies in play: FlatList React-Navigation 5 Redux Redux-Thunk.
Main Home page is a Feed of Posts (image, caption, name etc.). Upper right corner of home page is a Header Button that I press to go to the screen where I can create a Post. This is where an image, caption or both would get added to my home page.
Below is my FlatList code for reference. I have already tried to set removeClippedSubviews={false}. Doing so doesn't work and actually makes the problem worse.
<FlatList
ref={flatListRef}
data={allPosts}
extraData={[isLoading, isRefreshing, allPosts]}
refreshControl={
<RefreshControl
refreshing={isRefreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={item => item._id}
initialNumToRender={2}
renderItem={renderItem}
onEndReached={!endOfFeed && !oneTimeLoad && handleLoadMore}
onEndReachedThreshold={2}
ListFooterComponent={renderFooter}
ListHeaderComponent={renderHeader}
removeClippedSubviews={true} // Best way to optimize but sacrifices fast scroll down with blank space
//getItemLayout={(data, index) => ({ length: POST_CARD_HEIGHT, offset: POST_CARD_HEIGHT * index, index})}
//windowSize={20}
//maxToRenderPerBatch={15}
//updateCellsBatchingPeriod={50}
/>
My Stack Navigator is as shown before I press "Submit Post": HomeScreen => CreatePostScreen. Pressing "Submit" in CreatePostScreen dispatches an action that makes an API call to my backend server. Creates the post gets back the created post data including image uri and other metadata and then updates my redux state by prepending the newly created post to the old state.
I then make a call to navigation.pop() bringing me back to HomeScreen. When I see it again I am met with a Post with all relevant data except NO image is showing. I can see it only if I scroll down where it is out of view and then back to it.
Any insights would be helpful.
Sounds like the simple solution would be to use a different navigation method such as navigation.navigate('HomeScreen') or navigation.replace('HomeScreen'). You mentioned that if you scroll down past the post and then back up that the image reloads, so that makes me think using a different navigation might do the trick.
This was an issue related to my backend and how images get uploaded in general.
Because there is an AWSLambda function that converts uploaded images to different sizes for efficiency, popping back to the home feed immediately and trying to grab the just uploaded image resulted in a fail on the image load because it didn't exist yet in its resized format.
The Lambda runs pretty quickly but the state update was occurring faster.
I have a TextInput on an Overlay Component in my app. When the keyboard is opened, half the screen gets covered, including the TextInput. I did try the KeyboardAvoidingView component, but couldn't get the TextInput to be fully visible. I need some suggestion on how to move the components inside the Overlay, when the keyboard is enabled in react-native
it wld have been easier to answer if u had posted code, but still
keyboardAvoidview solve the common problem of views that need to move out of the way of the virtual keyboard. It can automatically adjust either its position or bottom padding based on the position of the keyboard
just add this under your largest view
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
all ur ui inside this...
</KeyboardAvoidingView>
There is a prop called keyboardVerticalOffset,
that is the distance between the top of the user screen and the react native view.
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled keyboardVerticalOffset={offsetValue}>
... your UI ...
</KeyboardAvoidingView>;
Value for keyboardVerticalOffset may be non-zero in some use cases. but for your case try to add some value.
If you want to know more about handling keyboard in react native check this
I have a simple overlay component that is rendered on top of certain items in a Flatlist. The list item component which is the parent component of the overlay sends down a dimensions object that lives on its state and gets updated onLayout. The overlay doesn't stretch quite fast enough when you go from portrait to landscape mode.
component: <View style={style.container}>
<View style={[style.overlay, dimensions()]} />
</View>
Any ideas how to make this respond faster?
I was able to achieve good results by using the solution from here:
Stretch Absolute Positioned element
I'm trying to get an element in a scrollview to always stay to the left of the screen. Kinda like the number rows in Excel. They stay to the left when scrolling horizontally but scroll also down when scrolled vertically. So far I tried animating the element by hooking up the onscroll element to it. It does work but it feels very choppy. It is fast but not fluid. Almost looks like the element is vibrating.
Are there any other techniques in react native to get the desired result? Here the important lines I'm using.
scrollPositionX: new Animated.Value(0),
scrollEventThrottle={16}
onScroll={Animated.event([{nativeEvent: {contentOffset: {x: this.state.scrollPositionX}}}] )}
<Animated.View style={[styles.times, {
transform: [{translateX: this.state.scrollPositionX}]
}]}>
...
</Animated.View>
A crude way to do it is to render the sticky columns outside of the horizontal ScrollView. Just make sure your stick and non sticky cells end up being the same height so everything lines up.
If you want to scroll vertically as well, wrap them both inside of another ScrollView.
<ScrollView>
<View>
// render the sticky cells
</View>
<ScrollView horizontal={true}>
// render the non sticky cells
</ScrollView>
</ScrollView>
The problem is that if you have a lot of rows, especially with more complex components within them, you'll have performance issues.
ListViews are better at handling lots of data, but I haven't found a way to make use of them for this scenario. You'd need one for both the sticky column and normal cells, and there's no way to keep them in sync without watching onScroll as you're doing.
I'm hoping someone has better way to do this though. I really need this functionality as well.