Here is styling of my nested ScrollView
<ScrollView style={{ flex: 1 }} refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => {
...
}}
/>}>
...
<ScrollView style={{ flex: 1 }}
nestedScrollEnabled={true}
>
...
</ScrollView>
...
</ScrollView>
Result of my code: Parent scroll view can scroll but child scroll view cannot. Child just render as long as the list is.
I believe {flex:1} in child is the main reason why child dont work. But I need flex:1 because I want it to occupy all the remaining spaces and I have other component didnt have a specific height.
I do not need the scolling function for parent and want to keep it as window size. I only need the refresh control for parent.
I tried to set parent scroll view as window height but the component will be cut out instead of squeezing the child scroll view.
Thankyou.
Related
Is there any way to create something like a ScrollView with dynamic height?
Details on what we're trying to do:
We created a Top Tab Bar (using createMaterialTopTabNavigator) within a ScrollView. Everything works fine, except the height of the ScrollView. Let's assume there are 3 tab screens with different heights: TabScreen1: 800, TabScreen2: 400, TabScreen3: 300... At rendering, the ScrollView takes the greatest height, and when Tab2 or 3 is selected, the height of our ScrollView remains at 800, so there is empty space for scrolling in Tab2 and 3.
As I promised, here is how we solved it.
In your class where you have your ScrollView you need a state like
const [activeTab, setActiveTab] = useState('tab1') //your default (first) tab
Later, you want to change that state every time you change tab:
<TabsStack.Screen
name={'tab1'}
component={
activeTab === 'tab1' ? Tab1Screen : DefaultScreen
}
listeners={{ focus: () => setActiveTab('tab1') }}
/>
Now every time a tab is unselected or rather not focused it will show DefaultScreen which is an empty view and has no height like:
const DefaultScreen = () => (
<Box
flex={1}
py={20}
alignItems="center"
justifyContent="center"
bg="background"
>
<ActivityIndicator size="large" color="white" animating />
</Box>
)
In my case (see question above), every time I switch from Tab1.1.1 to Tab1.1.2, Tab1.1.1 will change to DefaultScreen
Try something like this,
Fix the height of the parent widget to the maximum screen height you want that Tab Navigator to have.
<ListView or ScrollView>
<View style={{height: (width)/(0.8)}} >
<Tab.Navigator tabBar={(props) => <TabBar {...props} />}>
<Tab.Screen name="T1" component={T1} />
<Tab.Screen name="T2" component={T2} />
<Tab.Screen name="T3" component={T3} />
</Tab.Navigator>
</View>
</ ListView or ScrollView>
And for tabs do Something like this
T1 ->
<View style={styles.container}>
<ScrollView nestedScrollEnabled={true}>
<FlatList
numColumns={3}
data={allMedia}
keyExtractor={(item) => item.id}
listKey={(post) => `${post.id}D`}
renderItem={({ item }) => (Anything)}
scrollEnabled ={false}
/>
</ScrollView>
</View>
Remember to disable the scroll view Inside the FlatList of tabs and wrap with a ScrollView with nestedScrollEnabled={true}
Use this contentContainerStyle={{flex: 1}} inside scroll view
<ScrollView contentContainerStyle={{flex: 1}}>
...
// your tab
</ScrollView>
There is no need to put TabNavigator inside ScrollView. Put ScrollView inside of each TabScreen instead
Answering your question: if your ScrollView is the same height as the content then it doesn't scroll. You are probably talking about height of a contentContainer of a ScrollView. And the only wayto set it dynamically is to use onLayout to measure content height of currently selected tab, save this number to state and apply it as a height of in contentContainerStyle prop of a ScrollView. I don't recommend hacking it this way unless absolutely necessary though
I would like to scroll the parent ScrollView to that itemposition when I click Item in FlatList.
Since the actual data is flexible in length, can not calculate the height statically.
<ScrollView>
<View style={{height:300}}>
<Text>Test</Text>
</View>
<FlatList
scrollEnabled={false}
data={[1,2,3,4,5,6,7,8,9,10]}
renderItem={renderItem}
/>
</ScrollView>
ScrollToIndex in a FlatList can not be used because scrollEnabled is false.
I want to use ScrollTo of the parent ScrollView.
But onLayout is used forrenderItem, y is 0.
So I do not know the exact position.
How can I get the value I want?
First of all, Don't use FlatList inside ScrollView, use ListHeaderComponent prop in FlatList
Reference: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent
I was trying to make a view that I wanted to come over a flatlist so that on clicking it user can reach the top.But the flatlist was covering that element.
<View style={{backgroundColor:'#e6e6e6',flex:1,}>
<View style={{position:'absolute'}}>
<Text>Scroll To Reload</Text>
</View>
<FlatList refreshing={this.state.refresh} onRefresh={()=>this.refreshAllTweets()}
data={tweets}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) =>
<TweetItem onPress={()=>this.goToDetail(item.id)} onImagePress={()=>this.toggleModal(item.id)}
onCommentPress={()=>this.showComments(item.id)} tweet={item}/>}
/>
</View>
Each child in a view is rendered in order, and ultimately stacked on top of each other until all the children are rendered. As the view you want on the top is being rendered first it is going to be at the bottom. Change your code so that the view that you want on the top is rendered last. i.e. move it to the bottom of the view.
<View style={{backgroundColor:'#e6e6e6',flex:1}}>
<FlatList
refreshing={this.state.refresh}
onRefresh={()=>this.refreshAllTweets()}
data={tweets}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) => <TweetItem onPress={()=>this.goToDetail(item.id)} onImagePress={()=>this.toggleModal(item.id)} onCommentPress={()=>this.showComments(item.id)} tweet={item}/>}
/>
<View style={{position:'absolute', top: 0}}>
<Text>Scroll To Reload</Text>
</View>
</View>
As the view is now absolutely positioned you may wish to give it an actual position.
Update for comment
Flatlist covering the a element with absolute position
FlatLast has a prop called ListFooterComponent it takes a React Component Class, a render function, or a rendered element. So you could update your FlatList by adding the following prop.
<FlatList
...
ListFooterComponent={
<View>
<Text>Scroll To Reload</Text>
</View>
}
/>
This will attach the view as a footer to the FlatList, so it will be visible when the bottom of your FlatList is reached.
Check out the docs for more information about FlatLists.
I'm having some problems with zIndex and position whilst styling a drop down list (react-native-menu). I want to make the drop down list appear on top of all other components on this scene when it's clicked. I'm trying to use zIndex and position but maybe not doing it correctly?
In my code (below), I'm rendering a hierarchy where Card > CardSection > various subcomponents of each. The drop down list consists of the components MenuContext (config) and TopNavigation (main drop down list).
return (
<Card>
<CardSection style={{zIndex: 2}}>
<View style={thumbnailContainerStyle}>
<Image style={thumbnailStyle}
source={{ uri: "" }}
/>
</View>
<View style={headerContentStyle}>
<Text style={headerTextStyle}>Tam</Text>
<Text>tam#tam</Text>
</View>
<MenuContext style={{ flex:1, zIndex:6, position:'absolute', flexDirection: 'column', alignItems: 'flex-end' }} >
<TopNavigation/> //this is
</MenuContext>
</CardSection>
<CardSection style={{zIndex: 1}}>
<Text style={{zIndex: 2}}>{props.post.body}</Text>
</CardSection>
</Card>
)
So the drop down is a child of the first CardSection. I've got it to appear over it's own parent CardSection but I can't get it to appear on top of the second CardSection that renders after. So I can't get it to show on top of it's parent's sibling.
I'm reluctant to use some plugin or workaround.
Any ideas? Thanks!!
So what was making it so hard to render the popup menu above things on the z-axis was the sibling of it's parent. So what helped me get the results I needed was looking more macro and moving <ContextMenu/> higher in the component hierarchy, out of this component altogether and into it's parent.
I should have inferred this since the docs for the original package I used had ContextMenu in the entry point to the app and comments such as:
// You need to place a MenuContext somewhere in your application,usually at the root.
// Menus will open within the context, and only one menu can open at a time per context.
My mistake was getting lost in the micro world of zIndex and position and assuming that what looked like a styling problem should be solved with a styling solution. I forgot about the bigger picture.
I would like to play exactly this behavior.
A Tab component within a ScrollView should remain affix under the navbar when scroll, the problem is that applying the absolute position to the tab that relates to ScrollView.
This is the structure:
<ScrollView
style={styles.scrollView}
onScroll={this.onScroll}
scrollEventThrottle={16}>
<Image source={....} />
<Tab>...</Tab>
<View style={[styles.content, props.scrollableViewStyle]}>
// lorem ipsum..
</View>
</ScrollView>
Image:
How can I play this in React Native?