How can the image of an ImageBackground be positioned customly - reactjs

I have a ImageBackground over the whole screen, and I am trying to move the image, which is way bigger, to the left. When I try to position the image using left: -100 this happens (picture below). The ImageBackground is moved, but moves as a whole. What I need is to move only the underlying picture, not the View integrated in the ImageBackground. How can this be achieved?
Styling:
bgImageContainer: {
flex: 1
},
bgImage: {
left: -100
}
Code:
const screenSize = {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height - StatusBar.currentHeight
};
return (
<ImageBackground
source={bgImage}
resizeMode="cover"
style={{ ...screenSize, ...styles.bgImageContainer }}
imageStyle={styles.bgImage}
>
{/* content */}
</ImageBackground>
);

Try this work-around
<View style={{ ...screenSize, ...styles.bgImageContainer }}>
<Image source={bgImage} style={styles.bgImage} resizeMode="cover"/>
{/* content */}
</View>
Styling:
bgImageContainer: {
flex: 1
},
bgImage: {
position:'absolute',
width:SCREEN_WIDTH-100,
height: SCREEN_HEIGHT,
alignSelf:'flex-end' // if this not work make width full and add margin
}

wrap it with SafeAreaView component
import { SafeAreaView } from "react-native";
<SafeAreaView>
<ImageBackground
source={bgImage}
resizeMode="cover"
style={{ flex:1 }}
imageStyle={styles.bgImage}
>
{/* content */}
</ImageBackground>
</SafeAreaView>

Related

React Native status bar semi transparent

Is it possible to make StatusBar semi-transparent with an opacity of 0.8?
if I pass backgroundColor={"transparent"} like in the docs it becomes fully transparent without color. Docs https://reactnative.dev/docs/statusbar
<StatusBar style="light" backgroundColor={"red"} translucent />
You can give backgroundColor as #FF000080, and you can change color transparency by changing the last 2 digits of #FF000080
<StatusBar style="light" backgroundColor={"#FF000080"} translucent />
This is how i did it. Under StatusBar added a View with height: insets.top and style for StatusBar. This works for both OS platforms.
return (
<View>
<StatusBar style="light" translucent />
<View style={[styles.statusBar, { height: insets.top }]}></View>
<View
style={[
styles.contentContainer,
{
paddingLeft: insets.left,
paddingRight: insets.right,
},
]} >
</View>
</View>
);
}
const styles = StyleSheet.create({
statusBar: {
opacity: 0.8,
backgroundColor: "red",
},
});

Multiple onPress event on a single image component in React Native

I have this picture, and I want to have multiple onPress event for this image.
Example if I touch the head part it will call the function pressHead() and if I touch the chest part it will call the function pressChest().
So far I have tried plotting checkboxes on each part.
import React, { Component } from 'react';
import { View, Image, Alert } from 'react-native';
import { CheckBox } from 'react-native-elements';
export default class Screen extends Component {
pressHead() {
this.setState({checked1: !this.state.checked1})
Alert.alert('Pressed Head', '');
}
pressChest() {
this.setState({checked2: !this.state.checked2})
Alert.alert('Pressed Chest', '');
}
render() {
return (
<View style={{width: 200}}>
<Image
style={{width: 200, resizeMode: 'contain'}}
source={require('../../assets/images/body-diagram.png')}
/>
<CheckBox
containerStyle={{position: 'absolute', top: 22, right: 75, padding: 0}}
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checkedColor='#ff0000'
checked={this.state.checked1}
onPress={() => this.pressHead()}
/>
<CheckBox
containerStyle={{position: 'absolute', top: 70, right: 75, padding: 0}}
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checkedColor='#ff0000'
checked={this.state.checked1}
onPress={() => this.pressChest()}
/>
</View>
);
}
}
This does work. But if I try to use it on a larger device, the position absolute becomes not accurate enough.
Give the constant height for the image and overlay the checkboxes as same above respect to image. Since height is also made constant you don't find any position issues of the checkbox in any screen.
Example :
<View style={{width: 200, height: 600}}>
<Image
style={{width: 200, height: 600 ,resizeMode: 'contain'}}
source={require('../../assets/images/body-diagram.png')}
/>
You can do it by changing your image to <ImageBackground .. /> component after importing it from react-native.
After doing that you can place Touchable things inside of ImageBackground.
Example:
<ImageBackground source={require('../../assets/images/body-diagram.png')} style={{width: 200, height: 600, flexDirection: 'column'}}
<TouchableOpacity onPress={() => alert('first pressed')}>
<Text>First Area</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => alert('second pressed')}>
<Text>Second Area</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => alert('third pressed')}>
<Text>Third Area</Text>
</TouchableOpacity>
<ImageBackground/>

Detect active screen in React Native

Sorry for my bad English. I have built a navigation bar without using Tab Navigation from React Navigation, everything works fine except when I try to set an 'active' icon, I have handled it with states but the state restarts when I navigate to another window and render the bar again navigation.
I think I have complicated it a bit, but I need to capture the active screen to pass it as status and change the color of the icon to 'active' and the others disabled. I have tried with Detect active screen and onDidFocus but I only received information about the transition, I require the name or id of the screen.
I leave my code (this component is exported to each page where I wish to have the navigation bar). Please, the idea is to not use Tab Navigation from React Native Navigation.
export default class Navbar extends Component {
/** Navigation functions by clicking on the icon (image) */
_onPressHome() {
this.props.navigation.navigate('Main');
}
_onPressSearch() {
this.props.navigation.navigate('Main');
}
render() {
const { height, width } = Dimensions.get('window');
return (
<View style={{ flexDirection: 'row', height: height * .1, justifyContent: 'space-between', padding: height * .02 }}>
/** Icon section go Home screen */
<View style={{ height: height * .06, alignItems: 'center' }}>
<TouchableOpacity
onPress={() => this._onPressHome()}
style={styles.iconStyle}>
<Image
source={HOME_ICON}
style={{ width: height * .04, height: height * .04, }} />
<Text style={[styles.footerText, { color: this.state.colorA }]}>Inicio</Text>
</TouchableOpacity>
</View>
/** Icon section go Search screen */
<View style={{ height: height * .06, alignItems: 'center' }} >
<TouchableOpacity
onPress={() => this._onPressSearch()}
style={styles.iconStyle}>
<Image
source={SEARCH_ICON}
style={{ width: height * .04, height: height * .04, opacity: .6 }} />
<Text style={[styles.footerText, { color: this.state.colorB }]}>Inicio</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
For the navigation I used createStackNavigator and also
const drawerNavigatorConfig = {
contentComponent: props => <CustomDrawerContentComponent {...props}
/>,
};
const AppDrawer = createDrawerNavigator(drawerRouteConfig,
drawerNavigatorConfig);
I do not know if createDrawerNavigator is interfering with something, I read that it generates additional keys. Please help me with this.
import { useIsFocused } from '#react-navigation/native';
function Profile() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
check documentation
https://reactnavigation.org/docs/use-is-focused/
You can use this inViewPort library for checking the view port of the user. This is how you can user the library
render(){
<InViewPort onChange={(isVisible) => this.checkVisible(isVisible)}>
<View style={{flex: 1, height: 200, backgroundColor: 'blue'}}>
<Text style={{color: 'white'}}>View is visible? {this.state.visible </Text>
</View>
</InViewPort>
}

React Native ScrollView with single child component

I want to have a fullscreen ScrollView which contains all of the contents of my Home screen in my app. The issue I'm facing is that it works as expected when I have two child components for the ScrollView (I added a Text component just to try it), but not if I just have the single content View that I want.
The contents of <View style={style.content}> are taller than the screen size, so it should scroll. But when I remove <Text style={{margin: 60, marginTop: 800}}>Here is some text</Text> the entire screen goes white.
Here's what I've heard about ScrollView:
It needs a limited height (but I should have that since all of the content is currently static (no dynamic data) and all of my components there have a fixed height)
You need to use {flex: 1} on the components inside the ScrollView (I have this style set on my Container component)
Here is my Home component:
import React, { Component } from "react";
import {
StatusBar, StyleSheet, View, ScrollView, Text
} from "react-native";
import { LinearGradient } from "expo";
import MaterialCommunityIcon from "react-native-vector-icons/MaterialCommunityIcons"
import Color from "color";
import globalStyles from "../config/globalStyles";
import Container from "../components/Container/Container";
import Header from "../components/Header/Header";
import FullWidthImage from "../components/Images/FullWidthImage";
import MainFeedbackText from "../components/Text/MainFeedbackText";
import MainStatistics from "../components/Statistics/MainStatistics";
import Button from "../components/Buttons/Button"
export default class Home extends Component {
render() {
return (
<ScrollView style={{borderColor:"red", borderWidth: 2}}>
<Container>
<View style={style.content}>
<MainFeedbackText/>
<Button
text="START NEW WORKOUT"
textStyle={{fontSize: 24}}
buttonStyle={{
backgroundColor: globalStyles.colors.green,
paddingHorizontal: 20,
}}
icon={<MaterialCommunityIcon style={style.settings} name="dumbbell" color="white" size={30}/>}
/>
<Button
text="My workouts"
textStyle={{fontSize: 24, paddingRight: 40}}
buttonStyle={{
backgroundColor: Color("black").fade(0.8),
paddingHorizontal: 20,
margin: 20
}}
icon={<MaterialCommunityIcon style={style.settings} name="format-list-bulleted" color="white" size={20}/>}
/>
<MainStatistics/>
</View>
{/**TODO: ScrollView breaks when removing this line*/}
<Text style={{margin: 60, marginTop: 800}}>Here is some text</Text>
<StatusBar translucent={false}/>
<LinearGradient colors={["transparent", globalStyles.colors.dark]} style={style.gradient}>
<View style={style.image}>
<FullWidthImage requireSource={require("./lifting.jpg")}/>
</View>
</LinearGradient>
<Header/>
</Container>
</ScrollView>
);
}
}
const style = StyleSheet.create({
image: {
opacity: 0.3,
zIndex: -1,
},
gradient: {
position: "absolute",
top: 0,
zIndex: -1
},
content: {
flex: 1,
position: "absolute",
top: 80,
height: 4000,
}
});
Set contentContainerStyle={{ flex: 1 }} for ScrollView to become fullscreen.

React-native: how to remove list lines?

I'm using React Native, I want to remove lines from list but i can't,I set borderBottomWidth to 0 but it didn't work, this is my code:
import React from "react";
import { AppRegistry, Image, ImageBackground, StatusBar, StyleSheet, View,
FlatList } from "react-native";
import { Container, Content, Text, List, ListItem, Icon, Left, Body, Right,
} from "native-base";
const routes = [{"title":"Specials","icon":"menu"}, {"title":
"Home","icon":"home"}, {"title":"Shopping Cart","icon":"cart"},
{"title":"Wishlist","icon":"heart"},{"title":"My
Orders","icon":"menu"},{"title":"Categories","icon":"list"},
{"title":"Gift Vouchers","icon":"menu"},
{"title":"Affiliates","icon":"menu"},{"title":"Returns","icon":"menu"},
{"title":"My Account","icon":"menu"},
{"title":"Settings","icon":"menu"}, {"title":"Contact
Us","icon":"menu"},
{"title":"About","icon":"menu"},{"title":"Service
Center","icon":"menu"},
{"title":"Rate Us On Google Play","icon":"menu"},
{"title":"Logout","icon":"menu"}];
export default class SideBar extends React.Component {
render() {
return (
<Container>
<Content>
<ImageBackground source={require('../../assets/nav.png')} style={{
height: 150,
alignSelf: "stretch",
alignItems: "center",
flexDirection:'row'
}}>
<Image
style={{ height: 80, width: 80, borderRadius: 64, marginLeft: 25}}
source={{
uri: "http://safe-
pay.co/safepay/public/uploadedimg/user/avatar.png"
}}
/>
<View style={{flexDirection: 'column', marginLeft: 25}}>
<Text style= {{color: 'white'}}>Nima</Text>
<Text style={styles.emailText}>Nima33#gmail.com</Text>
</View>
</ImageBackground>
<List
dataArray={routes}
renderRow={data => {
return (
<ListItem
style={{borderBottomWidth: 0}}
button
onPress={() => this.props.navigation.navigate(data.title)}
icon>
<Left>
<Icon name={data.icon} style={{color:'gray'}}/>
</Left>
<Body>
<Text>{data.title}</Text>
</Body>
</ListItem>
);
}}
/>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
emailText: {
fontSize: 12,
color: 'white'
}
})
This is the output:
I set noLines and noBottomBorder as prop but they didn't work,If i set ottomBorderWidth:2 the bottom line size increase in width and height, Is these lines must be in list or there is any eay to remove it?
You should set noBorder as prop: <ListItem noBorder>.
Try to apply borderBottomWidth:0 in <List> instead of <ListItem> like below.
<List
dataArray={routes}
containerStyle={borderBottomWidth: 0}
renderRow={data => {
return (
<ListItem
style={{borderBottomWidth: 0}}
button
onPress={() => this.props.navigation.navigate(data.title)}
icon>
<Left>
<Icon name={data.icon} style={{color:'gray'}}/>
</Left>
<Body>
<Text>{data.title}</Text>
</Body>
</ListItem>
);
}}
/>
Apply borderBottomWidth:0 to ListItem and Body. If there is no Body then ListItem should be good enough.
For your specific case, just set the borderColor:white.
You can set the property property bottomDivider as false at the ListItem component.

Resources