I'm having a RefreshControl attached to a ScrollView. It all works as expected but initially (when I didn't start scrolling), there's always showing a RefreshControl on the top right. When I start scrolling, it disappears.
Any idea how to get rid of that?
Code is nothing special, if you want, i'll give it here:
// ...
export default class SomeList extends React.Component
{
// ...
render() {
return <View style={{flex: 1}}>
<CustomNavbar />
<ScrollView
style={{marginTop: 35}}
refreshControl={
<RefreshControl
tintColor={$.config.colors.style}
onRefresh={() => this._refreshList()}
refreshing={this.state.listRefreshing}
/>
}
>
{this._renderItems()}
</ScrollView>
</View>
}
}
This is a bug in react-native which was introduced in version 0.31 or so.
It was fixed in version 0.34.1 (see this commit), so I guess you're using a previous version.
If you do not wish to upgrade, you can temporarily solve it by settings the background color of the refresh control to transparent:
<RefreshControl style={{backgroundColor: 'transparent'}}/>
Related
I'm running a RN app using native-base for styling. I have four elements on my homepage: a header, a tab view from vreact-native-tab-view that contains a ScrollView that takes up about 70% of the viewport, and two smaller 100% width elements at the bottom.
However, the scrollview fills up more than 100% of the viewport and the two smaller elements get pushed to the bottom.
I looked in my element inspector and can apply a flexShrink to some of the many divs, but I'm not sure which one that is in my code because it's div hell when you use react-native. React devtools also has the same problem, except it's View hell.
So, two questions:
How can I ensure the scroll container doesn't fill up more than it should on the page?
How can I effectively debug react native when both chrome and react dev tools are a mess?
For reference, here's how I've styled so far:
Home.tsx:
<View flex={1}> // applied a flex for the entire homepage
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
renderTabBar={renderTabBar}
onIndexChange={setIndex}
initialLayout={{ width: layout.width, height: "100%" }}
/>
<View width="100%">
<Center width="100%">
<StrengthSlider />
</Center>
<AdMobBanner
...props
/>
</View>
</View>
Teas.tsx:
<View flex={1} bg="white">
<ScrollCards teas={blackTeas} />
</View>
ScrollCards.tsx:
<ScrollView>
<Center>
{teas.length > 0 &&
teas.map((teaObj) => (
<TeaCard id={teaObj.id} teaData={teaObj.data} key={teaObj.id} />
))}
</Center>
</ScrollView>
EDIT:
Code Sandbox link: https://codesandbox.io/s/gracious-sammet-l4tqz?file=/src/App.js&resolutionWidth=402&resolutionHeight=675
Note that the admob footer remains underneath the cards content. It should be sticky and remain always at the bottom of the screen. I also noticed that when I'm not using the header from the MainStackNavigator the footer works as intended - i.e. it remains sticky at the bottom - but I don't see why using the header (AppBar) component should interfere with my footer.
The proper solution to get the result you want is to add a flexBasis to the TabView like:
<TabView
style={{ flexBasis: 0 }}
// rest of the code
/>
Why?
The TabView has a default style of flex: 1, overflow: 'hidden' (see source code) causing it to expanded to the size of its biggest child. The flexBasis prevents this and makes sure the tabview get the correct height.
Resource: This is a nice article about flexBasis vs width/height: https://mastery.games/post/the-difference-between-width-and-flex-basis/
Debugging styling in React-Native doesn't have the best developer experience. There are some things you can use to help you with debugging styling:
RN inspector: As Berci mentioned, React native has a dev menu where you can select "show inspector" that kinda acts like "inspect element" in a browser. It is a good tool to debug elements you can see, it also helps with debugging input/tab events.
Color: Most often I just use old fashioned colored borders & background to get a clear view of where elements are & their size/overlaps.
Comments & Simplify: Feel free to comment out components you're not interested in and replace complex components/views like ScrollCards with just a simple colored view. This can help prevent multiple behaviours from influencing the thing you're trying to debug
Browser inspect & React devtools: If you happen to run your RN app in the browser, then getting familiar with those tools will help you loads. Just keep in mind that React & React-Native isn't the same.
When you debug visuals, the best way is start at the top layer and work you way down. Color the elements & feel free to comment out elements to get you a clearer view of the problem. Keep digging down until you find the problem, don't be afraid to look into the source code of the packages you use, it often helps clarify (unexpected) behaviours.
You could try to replace
<View flex={1}> // applied a flex for the entire homepage
in Home.tsx with
<View flex="1 1 0">
Working example here (is your code with that line modified).
As for debugging I can only suggest what is already suggested on react native Debugging page. Have you tried React Developer Tools yet? In chrome you can also add it as an extension from this link.
I am not sure if there is any difference between chrome extension and the npm package but the extension was enough for me at least (for now).
The only problem is that I also struggled debugging on codesandbox since the extension is definitely not working on javascript online editors (but probably the npm package doesn't either for this specific case)
Try this - https://snack.expo.dev/fL0OgQ9uS
import React from 'react';
import { View, Image, StyleSheet,ScrollView,Text } from 'react-native';
const styles = StyleSheet.create({
container: {
paddingTop: 50,
flex:1,
backgroundColor:'aqua',
},
tinyLogo: {
width: 200,
height: 200,
},
header:{
backgroundColor:'green',
paddingBottom:20,
},
footer:{
backgroundColor:'green',
paddingTop:20,
}
});
const DisplayAnImage = () => {
return (
<View style={styles.container}>
<View style={styles.header}><Text>header</Text></View>
<ScrollView>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
<Image
style={styles.tinyLogo}
source={require('#expo/snack-static/react-native-logo.png')}
/>
</ScrollView>
<View style={styles.footer}><Text>footer</Text></View>
</View>
);
}
export default DisplayAnImage;
I am experiencing an odd bug with the React Native Navigation v5 headerRight Buttons. I currently have a TouchableOpacity set as a headerRight component in the react native navigation screen; however, the onPress event is not being triggered. There seems to be an invisible object in the middle of the header (title area) that has an absolute position, which prevents the onPress event from being registered. I tried playing around with the zIndex and headerMode values; however, the button is still not pressable. I can only press the button when it is placed on the far right of the screen (i.e. marginRight: 0). Any help would be greatly appreciated.
For reference, I am encountering the same issues as the following thread: https://github.com/react-navigation/react-navigation/issues/7052
Example of my Code
<StackNavigator.Navigator headerMode='screen'>
<StackNavigator.Screen
name='Home'
component={HomeScreen}
options={{
headerRight: () => (
<TouchableOpacity
onPress={() => {}}
>
<Text>Button Text</Text>
</TouchableOpacity>
),
}}
/>
</StackNavigator.Navigator>
Updating to the following packages seems to have resolved it for me:
"#react-navigation/stack": "5.9.3",
"#react-navigation/drawer": "5.9.3",
"#react-navigation/native": "5.7.4",
Try to give higher values to zIndex may be 100 or give headerMode: float if that not also not works try updating your packages .
What I'm facing:
I have a StackNavigator in which I want to set a ImageBacgkround to all it's children screens. The problem is, I've already setted my StackNavigator cardStyle: { backgroundColor: 'transparent' }, following React Navigation Docs, and wrapped it inside a ImageBackground but still can't get it working.
What I've tried:
//My navigator component is more complex, but the concept looks something like this
//for both navigators
const Stack = createStackNavigator();
const MyStackNavigator = () => (
<ImageBackground source=('../assets/my-background.png') resizeMode='cover' style={{flex: 1}}>
//If I change BackgroundColor to 'red' or anything like that, it works fine
//so I think the problem isn't related to styling properties
<Stack.Navigator screenOptions={{cardStyle: { BackgroundColor: 'transparent' } }}>
<Stack.Screen name='Screen1' component={Component1}/>
<Stack.Screen name='Screen2' component={Component2}/>
<Stack.Screen name='Screen3' component={Component3}/>
</Stack.Navigator>
</ImageBackground>
);
export default App() => (
<MyStackNavigator />
);
I've done the same thing in a DrawerNavigator inside my navigator component passing sceneContainerStyle: { backgroundColor: 'transparent' } }} and it actually works. It seems like my StackNavigator ain't rendering it's parent components correctly.
One of my StackNavigator's screens:
One of my DrawerNavigator's screens:
Both navigator's screens layout are wrapped in a transparent container View, so as you can see, the drawer screen is rendering background correctly but the stack screen isn't. Maybe I'm passing wrong props to my StackNavigator?
well with react-navigation 6 you can use the theming option to customize the look for the background to be transparent (Default is rgb(242,242,242)) use a NavigatorContainer to apply the theme
here is an answer that may help
When I tried just to render the HomeScreen component not using Stack.Screen I was able to get 100% width but when I tried to use code bellow, 100% width screen is not working
const HomeScreen = () => {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'red'}}>
<Text>Home Screen</Text>
</View>
);
}
const MainContainer = () => {
return (
<NavigationContainer >
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
Not only that, the width is zero if you set headerShown: false.
Just remove the outer View of the NavigationContainer. It works for me.
Can you try with display: flex and remove flex:1
Were you running the remote debugger when you were having this issue? I had the same problem and it resolved when I turned it off.
It seems like it might be a slow load issue and the stylesheets aren't being applied before rendering, so the screen is taking the width of the header text (I may be completely wrong about this though). When I removed the style prop from my View component, saved it, then put it back and saved again it temporarily resolved the issue until I reloaded Expo.
Im new at react native and I'm trying to do a simple aplication.
I just put a text and this is result in Nexus 5:
I understood that putting SaveAreaView this would be fixed but it dosen't.
return (
<SafeAreaView style={{flex: 1}}>
<Text style={styles.principalTitle}>Just a text</Text>
</SafeAreaView>
);
How I can control the top bar for the text apears in a visible zone? Thank you.
The purpose of SafeAreaView is to render content within the safe area
boundaries of a device. It is currently only applicable to iOS devices
with iOS version 11 or later. - SafeAreaView
In your case the SafeAreaView has no effect, but you can pass a marginTop to the view or directly to your text. E.g. :
return (
<SafeAreaView style={{flex: 1, marginTop: 20 }}>
<Text style={styles.principalTitle}>Just a text</Text>
</SafeAreaView>
);
Following Tim reference answer I improved him code.
With React Native you can control status bar height:
import {... , StatusBar} from 'react-native';
return (
<SafeAreaView style={{flex: 1, paddingTop: StatusBar.currentHeight }}>
<Text style={styles.principalTitle}>Just a text</Text>
</SafeAreaView>
);
I prefered padding for conserve Background.
Thank you!