I'm using Navigator component in React-Native.
//...
render() {
return (
<Navigator
ref="navigator"
navigationBar={this.renderHeader()}
sceneStyle={styles.container}
initialRoute={{type: 'Home'}}
renderScene={this.renderScene.bind(this)} />
);
}
Now I need to set a background image fixed for all scenes, but I can't wrap Navigator component inside another View.
// No errors but background is ignored
render() {
return (
<View style={styles.navigatorContainer}>
<Image source={require('image!logo-big')} style={styles.background} />
<Navigator
ref="navigator"
navigationBar={this.renderHeader()}
sceneStyle={styles.container}
initialRoute={{type: 'Home'}}
renderScene={this.renderScene.bind(this)} />
</View>
);
}
var styles = StyleSheet.create({
container: {
flex: 1
},
background: {
position: 'absolute',
left: 0,
top: 0,
width: 1024,
height: 768
},
navigatorContainer: {
flex: 1,
backgroundColor: '#FF0000'
}
});
If I set the backgroundColor to class NavigatorContainer, I can see red background but it doesn't work with image.
Any suggestions?
Found the fix: to show the background image you must set the navigatorContainer's backgroundColor to 'transparent'.
Related
I am using the default stack from react navigation, and in my navigator screen options I have my own custom header header: (props) => <Header props={props} />. In my screen, I have a background colour, and in my SafeAreaView I have a background colour. For illustration I have set them both to the same.
In my custom header I am applying margin of 15 horizontally as well as to the top. So it is the colour underneath the custom header.
My question is this: Where is this header background colour being set? (the light grey one)
Here you can see what I mean
I have tried headerStyle {backgroundColor}, but no difference (i believe because using header overrides a lot of these options? Unsure though as it is not stated in the documentation.)
For reference, I am basing it off of this documentation: https://reactnavigation.org/docs/native-stack-navigator/#options
However it appears that this background colour is being set somewhere else entirely? And so I'm not sure where.
I realize setting headerTransparent and applying margin for each screen is a viable solution but I figure there is a better way to simply set the background colour of this space correctly.
edit with header component:
export default function Header({ props }) {
const { navigation, route, options, back } = props;
const title = getHeaderTitle(options, route.name);
return (
<View style={styles.header}>
<View style={styles.container}>
{back && (
<IconButton
type="ion"
name="chevron-back"
size={26}
iconStyle={styles.backButton}
onPress={navigation.goBack}
/>
)}
<Text style={styles.title}>{title}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
width: screenWidth - 30,
height: 60,
borderRadius: 10,
padding: 15,
marginTop: 15,
backgroundColor: colors.white,
alignSelf: "center",
flexDirection: "row",
alignItems: "center",
},
backButton: {
zIndex: 1,
},
title: {
flex: 1,
textAlign: "center",
flexDirection: "column",
fontSize: 24,
fontWeight: "bold",
// marginLeft: -26,
},
header: {
backgroundColor: colors.neutral95,
},
});
I put a button in absolute position to on WebView.
This button works on any simulators and my iPhone 5s real device, but not work on iPhone Plus real device.
The button reacts when tapping, but doesn't fire onPress. It works when set position as relative.
All simulators and devices are same iOS version (12.2).
Does anyone know about this issue?
Environments
React Native 0.56
iOS 12.2
import React, { Component } from 'react';
import { ActivityIndicator, BackHandler, Keyboard, NetInfo, Platform, ScrollView, StatusBar, StyleSheet, Text, TouchableOpacity, View, WebView } from 'react-native';
import { Button, Icon } from 'react-native-elements'
export default class SignInScreen extends React.Component {
constructor(props) {
super(props)
}
handleBackPress() {
this.refs['WEBVIEW_REF'].goBack()
return true
}
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="white" barStyle="dark-content" />
<WebView
ref="WEBVIEW_REF"
bounces={false}
source={{ uri: 'https://example.com' }}
style={styles.container}
/>
<Button
onPress={this.handleBackPress.bind(this) }
buttonStyle={styles.buttonBack}
title=""
icon={{
name: 'chevron-left',
type: 'material-community',
iconStyle: { color: global.color.normal }
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
buttonBack: {
width: 45,
height: 45,
position: 'absolute',
left: 10,
bottom: 60,
backgroundColor: '#bfbfbf',
opacity: 0.9
},
container: {
flex: 1,
paddingTop: 25,
backgroundColor: '#fff'
},
});
Position absolute does not work properly in some cases at ios. you should wrap in a :
<View style={{position:'absolute',...other styles}}>
<Button/> // without position style
<View>
Use padding on your button,it will solve.
You need to use Dimensions in this case. For example in your case you can use it like this:
buttonBack: {
width: Dimensions.get('window').width/100*10,
height: Dimensions.get('window').height/100*10,
position: 'absolute',
left: Dimensions.get('window').width/100*2,
bottom: Dimensions.get('window').height/100*5,
backgroundColor: '#bfbfbf',
opacity: 0.9
},
Dimensions.get('window').width/100*10 means 10 percent of total device
screen width and same for height.
Dimensions work as device specific. So it will take the same position according to Device Screen Height and Width.
Fixed by wrapping absolute position View.
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="white" barStyle="dark-content" />
<WebView
ref="WEBVIEW_REF"
bounces={false}
source={{ uri: 'https://example.com' }}
style={styles.container}
/>
<View style={styles.navContainer}>
<Button
onPress={this.handleBackPress.bind(this) }
buttonStyle={styles.buttonBack}
title=""
icon={{
name: 'chevron-left',
type: 'material-community',
iconStyle: { color: global.color.normal }
}}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
buttonBack: {
width: 45,
height: 45,
left: 10,
backgroundColor: '#bfbfbf',
opacity: 0.9
},
// moved from buttonBack style
navContainer: {
position: 'absolute',
bottom: 60
},
//
container: {
flex: 1,
paddingTop: 25,
backgroundColor: '#fff'
},
});
I have given an ImageBackground component and I want it to take the whole screen but it appears to have small paddings even if I resize twice or more the image. Where does it comes from ?
Here is the code of the component
import React from "react";
import { View, Text, Button, ImageBackground, StyleSheet } from "react-
native";
export class HomeScreen extends React.Component {
static navigationOptions = {
//To hide the NavigationBar from current Screen
header: null
};
render() {
return (
<ImageBackground source={require('../imgs/bgx.png')} style={
styles.container }>
</ImageBackground>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'stretch',
resizeMode: 'stretch'
}
});
Make sure your source image does not have any transparency around.
Set width: '100%' and height: '100%' to the ImageBackground component. Does it change anything?
Add width='100%' and height='100%'
I need to set width and height of ListView. While setting width works as expected, setting height has no effect and ListView is always stretching into almost bottom of the screen (there is only margin between bootom of screen and bottom of ListView). I am creating ListView in render method this way:
<ListView ref={component => this._stationsListFrom = component} style={styles.stationsList} dataSource={this.state.dataSource} renderRow={(rowData) => <Text>{rowData}</Text>} />
This is its style:
stationsList: {
backgroundColor: 'white',
height: 0,
}
I have also tried to set its height in a method by this command:
this._stationsListFrom.setNativeProps({height: 200});
When I have tried to set width using this command, it worked. But setting height does nothing.
How can I set height of ListView (for example, in the case of TextInput its not a problem) to desired value? Only way I wound is to use bottom margin, but that is not the way I want to use.
I am testing on iOS only (for the case it works differently on Android).
My code:
import React, { Component } from 'react';
import Dimensions from 'Dimensions';
import {
AppRegistry,
StyleSheet,
Text,
TextInput,
ListView,
Button,
View
} from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: '#D8CD36',
padding: 25
},
label: {
textAlign: 'left',
color: '#333333',
fontSize: 20,
margin: 5,
},
textInput: {
height: 40,
borderColor: 'black',
borderWidth: 2,
padding: 7,
},
stationsList: {
backgroundColor: 'white',
height: 0,
},
separator: {
flex: 1,
height: StyleSheet.hairlineWidth,
backgroundColor: '#8E8E8E',
},
menuButton: {
},
},
);
export default class TestApp extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.state = { dataSource: ds.cloneWithRows(['Žilina', 'Košice', 'Vrútky']), };
}
render() {
return (
<View style={styles.container}>
<Text style={styles.label}>
Z
</Text>
<TextInput ref={component => this._textInputFrom = component} style={styles.textInput} placeholder="Východzia stanica" onChangeText={this.fromTextChange.bind(this)} onLayout={(event) => { this.correctMenuFromWidth(event.nativeEvent.layout) }} renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator}/>} />
<Text style={styles.label}>
Do
</Text>
<TextInput style={styles.textInput} placeholder="Cieľová stanica"/>
<ListView ref={component => this._stationsListFrom = component} style={styles.stationsList} dataSource={this.state.dataSource} renderRow={(rowData) => <Button onPress={this.menuFromButtonPressed} style={styles.menuButton} title={rowData} />} />
</View>
);
}
correctMenuFromWidth(layout) {
const {x, y, width, height} = layout;
this._stationsListFrom.setNativeProps({marginTop: -74, width: width});
}
menuFromButtonPressed() {
};
fromTextChange() {
this._textInputFrom.setNativeProps({text: 'Kraľovany'});
this._stationsListFrom.setNativeProps({height: 200});
};
}
AppRegistry.registerComponent('TestApp', () => TestApp);
Move ListView inside wrapper and set height to wrapper:
<View style={{height: 200}}>
<ListView .../>
</View>
From ScrollView docs (ListView uses ScrollView):
Keep in mind that ScrollViews must have a bounded height in order to work, since they contain unbounded-height children into a bounded container (via a scroll interaction). In order to bound the height of a ScrollView, either set the height of the view directly (discouraged) or make sure all parent views have bounded height.
I wanna to place a ScrollView and Button in a row, but It doesn't work, neither paddingLeft or width.
Without the Button the NaviScrollView will fill the hole view even I had set the width; with the Button and the Button will fill the hole view. Why?
export class Home extends Component {
render() {
return (
<View style={ styles.container }>
<NaviScrollView data= { fakeData }/>
<Button title="添加" color='gray' style={{right:0, width:20}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'red',
top: 20,
height: 44
},
})
class NaviScrollView extends Component {
render(){
return (
<ScrollView horizontal={true}>
{
this.props.data.map((item, index) =>
<Button key={ index } title={ item.title } onPress={ () => this._buttonPressed(item.title + item.url)}
color = 'black'/>)
}
</ScrollView>
);
}
}
Using style property : flexDirection : 'row' for View tag to organize childrens in a row or flexDirection : 'column' to organize childrens in a column.
I make a simple example base on your project. I didn't know its similar with your project or not but just take a look.
export default class Home extends Component {
render(){
return(
<View style={ styles.container }>
<ScrollView>
<Text>ABC</Text>
<Text>DEF</Text>
<Text>GHI</Text>
<Text>JKL</Text>
<Text>NMO</Text>
</ScrollView>
<TouchableOpacity style={styles.press}>
<Text>Press Me</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
button : {
width : 50,
height : 50
},
container: {
flexDirection : 'row',
backgroundColor: 'red',
top: 20,
height: 44
},
press: {
width: 150,
padding: 10,
backgroundColor : 'yellow'
}
})