I am trying to use a CustomCallout with a ImageBackground in it. I notice a really strange behavior when testing the application on two different devices (both Android). The image is showed correctly on the older device with lower display, but on the new device (p30 lite) the image is not appearing.. any ideas? here is my code:
class CustomCallout extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.calloutStyle}>
<View>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<ImageBackground
source={{ uri: this.props.image }}
style={styles.bgImage}
>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</ImageBackground>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
CustomCallout.propTypes = propTypes;
const styles = StyleSheet.create({
calloutStyle: {
height: 200,
width: 280,
backgroundColor: '#61adc8',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
padding: 12,
borderRadius: 20,
shadowColor: 'black',
overflow: 'hidden'
},
bgImage: {
width: '100%',
height: '100%',
justifyContent: 'flex-end',
},
placeRow: {
flexDirection: 'row'
},
placeHeader: {
height: '80%'
},
placeDetail: {
justifyContent: 'space-between',
height: '10%'
},
placeRating: {
height: '10%',
justifyContent:'flex-start',
},
titleContainer: {
backgroundColor: 'rgba(0,0,0,0.5)',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
borderRadius: 10,
alignItems: 'center'
},
title: {
color: 'white',
fontSize: 20
}
});
export default CustomCallout;
We cant put ImageBackground wherever we want.. I don't know the exact theory. But Just put the ImageBackgroung tag outside the view and try to even put on different views too.. If anyone know plz correct me. Here is a working example.
Put ImageBackground to entire component
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Or you can put to only both components
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</ImageBackground>
</View>
</View>
);
}
}
or put ImageBackground to inside view only
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Try this out and let me know the result.. :)
Related
It isn't turning out how I want it to be
Figma Design and the
Coded in React Native
I want it to float and have a transparent background while being stuck to the bottom of the screen like I have shown in the Figma design.
const TicketDetails = () => {
return (
<View style={{backgroundColor:'#D0DEEA', flex:1, position: 'relative'}}>
<ScrollView style={styles.containerMain} showsVerticalScrollIndicator={false}>
<View style={styles.topNavigation}>
<Back/>
<Close/>
</View>
<View style={styles.headingContainer}>
<Text style={styles.heading}>Create New Ticket</Text>
</View>
<View style={styles.formContainer}>
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
<Text style={styles.formHeading}>Enter Ticket Details</Text>
<Filter/>
</View>
<CustomDropdown data={serviceType} text={'Service Type'} placeholderText={'Select Service Type'}/>
<CustomInput2 heading={'Assign Dealer'} placeholder={''}/>
<CustomInput2 heading={'HMR'} placeholder={'Enter HMR Value'}/>
<CustomDropdown data={criticality} text={'Criticality'} placeholderText={'Select Criticality'}/>
<CustomDropdown text={'Customer Concerns'} placeholderText={'Select..'}/>
<CustomInput2 heading={'Expected Date'} placeholder={'31 Dec 2022'}/>
</View>
</ScrollView>
<View style={styles.nextButton}>
<Submit text='Next' style={{position:'absolute'}}/>
</View>
</View>
)
}
const styles = StyleSheet.create({
containerMain:{
marginTop:60,
backgroundColor:'#D0DEEA',
opacity:1,
position:'relative'
},
formContainer:{
flex:0.7,
backgroundColor: 'white',
borderRadius: 35,
marginTop:40,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.4,
},
nextButton:{
flexDirection: 'column',
flexGrow: 1,
justifyContent: 'space-between',
},
topNavigation:{
marginLeft:13,
marginRight:13,
flexDirection: 'row',
justifyContent: 'space-between'
}
})
It's either there at the scroll end or does not appear to be floating.
example for you:
import React from 'react';
import { Image,View, ScrollView,
Text,TouchableOpacity } from 'react-
native';
const logo = {
uri:
'https://reactnative.dev/img/tiny_logo.png',
width: 64,
height: 64
};
const App = () => (
<View>
<ScrollView>
<Text style={{ fontSize: 96 }}>Scroll me
plz</Text>
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Image source={logo} />
<Text style={{ fontSize: 96 }}>Scrolling
down</Text><Image source={logo} />
<Text style={{ fontSize: 96 }}>What's the
best</Text>
<Text style={{ fontSize: 96 }}>Framework
around?</Text>
<Text style={{ fontSize: 80 }}>React
Native</Text>
</ScrollView>
<TouchableOpacity style={{
position: 'absolute',
width: '90%',
height: 50,
alignItems: 'center',
justifyContent: 'center',
bottom: 30,
left:15,
right:5,
backgroundColor:'#ff00ff',
borderRadius:20
}} >
<Text >text</Text>
</TouchableOpacity>
</View>
);
export default App;
This request is a basic CSS knowledge.
Add position: 'relative' to the styles of the area that should snap under.
Add position: 'absolute' to your button styles. And your wish will come true.
If that doesn't help please share your sample code.
// this card component
<View style={{position: 'relative'}}>
// this button component
<TouchableOpacity style={{position: 'absolute', bottom: 0}}>
<Text>Hello World</Text>
</TouchableOpacity>
</View>
const TicketDetails = () => {
return (
<View style={{backgroundColor:'#D0DEEA', flex:1, position: 'relative'}}>
<ScrollView style={styles.containerMain} showsVerticalScrollIndicator={false}>
<View style={styles.topNavigation}>
<Back/>
<Close/>
</View>
<View style={styles.headingContainer}>
<Text style={styles.heading}>Create New Ticket</Text>
</View>
<View style={styles.formContainer}>
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
<Text style={styles.formHeading}>Enter Ticket Details</Text>
<Filter/>
</View>
<CustomDropdown data={serviceType} text={'Service Type'} placeholderText={'Select Service Type'}/>
<CustomInput2 heading={'Assign Dealer'} placeholder={''}/>
<CustomInput2 heading={'HMR'} placeholder={'Enter HMR Value'}/>
<CustomDropdown data={criticality} text={'Criticality'} placeholderText={'Select Criticality'}/>
<CustomDropdown text={'Customer Concerns'} placeholderText={'Select..'}/>
<CustomInput2 heading={'Expected Date'} placeholder={'31 Dec 2022'}/>
</View>
</ScrollView>
<TouchableOpacity style={{
position: 'absolute',
width: '90%',
height: 50,
alignItems: 'center',
justifyContent: 'center',
bottom: 30,
left:15,
right:5,
backgroundColor:'#ff00ff',
borderRadius:20
}} >
<Text >text</Text>
</TouchableOpacity>
</View>
)
}
I'm trying to put the name's on the left and the rank on the right. I tryed the flexDirection row with a space between or space evenly but it still doesn't work.
Do you have any solution for that ?
Also my function :
renderRanking = () => {
return this.state.ranking.map((element) => {
return (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-’‘’',
}}>
<View style={{flex: 1}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
</View>
);
});
};
And my render
render() {
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'black'}}>
<View style={{flex: 1, backgroundColor: 'black'}}>
<ScrollView>
<View
style={{
flex: 1,
}}>
<Text>{this.OpenDecibels()}</Text>
</View>
<View style={{paddingBottom: 30}}>
<PageControlView defaultPage={1}>
<View>{this.renderRanking()}</View>
</PageControlView>
</View>
</ScrollView>
</View>
</SafeAreaView>
);
}
}
Try this way
<View
style={{
flexDirection: 'row',
justifyContent: 'space-’‘’',
}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
You should try below snippet in your renderRanking function.
renderRanking = () => {
return this.state.ranking.map((element) => {
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
);
});
};
Also change
<PageControlView defaultPage={1}>
<View>{this.renderRanking()}</View>
</PageControlView>
To
<PageControlView defaultPage={1}>{this.renderRanking()}</PageControlView>
I am new to react native, I have a screen that its quite long and when like to use scrollview in order to allow all the important to be viewed by scrolling.
When I add scrollview the information disappears and I don't know why. What is the best way to fix this?
The screen without scrollview
The screen with scrollview
Here is my code.
export default class FindScreen extends React.Component {
render() {
return (
<View style={{height: 200}}>
<Image
style={{width: '100%', height: '100%'}}
source={require('./image.png')}
/>
<ScrollView>
<View>
<Text style={styles.MainText}>Directions</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>Address
{'\n'}
Address
{'\n'}
Address
{'\n'}
Address</Text>
<View>
<Entypo name="location-pin" size={30} color={'#E8AA65'} style={styles.IconImage} />
</View>
</View>
<View>
<Text style={styles.MainText}>Phone</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>+44 0000 000000</Text>
<View>
<Entypo name="phone" size={30} color={'#E8AA65'} style={styles.IconImage2} />
</View>
</View>
</View>
<View>
<Text style={styles.MainText}>Email</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>example#gmail.com</Text>
<Entypo name="mail" size={30} color={'#E8AA65'} style={styles.IconImage3} />
</View>
</View>
</View>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
MainText: {
paddingLeft: 20,
paddingTop: 40,
fontSize: 16,
color: '#E8AA65'
},
MainView:
{
flexDirection: 'row',
},
IconImage: {
paddingLeft: 160,
paddingTop: 45,
},
IconImage2: {
paddingLeft: 160,
paddingTop: 15
},
IconImage3: {
paddingLeft: 70,
paddingTop: 20
},
AddressText: {
paddingLeft: 20,
paddingTop: 20,
fontSize: 16
}
});
Your first View has only 200 of height... and that's encapsulating all the content.. You probably wanted only on the image so change the first one to flex:1 and create another with the 200 height
export default class FindScreen extends React.Component {
render() {
return (
<View style={{flex: 1}}>
<View style={{height: 200}}>
<Image
style={{width: '100%', height: '100%'}}
source={require('./image.png')}
/>
</View>
<ScrollView>
<View>
<Text style={styles.MainText}>Directions</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>Address
{'\n'}
Address
{'\n'}
Address
{'\n'}
Address</Text>
<View>
<Entypo name="location-pin" size={30} color={'#E8AA65'} style={styles.IconImage} />
</View>
</View>
<View>
<Text style={styles.MainText}>Phone</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>+44 0000 000000</Text>
<View>
<Entypo name="phone" size={30} color={'#E8AA65'} style={styles.IconImage2} />
</View>
</View>
</View>
<View>
<Text style={styles.MainText}>Email</Text>
<View style={styles.MainView}>
<Text style={styles.AddressText}>example#gmail.com</Text>
<Entypo name="mail" size={30} color={'#E8AA65'} style={styles.IconImage3} />
</View>
</View>
</View>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
MainText: {
paddingLeft: 20,
paddingTop: 40,
fontSize: 16,
color: '#E8AA65'
},
MainView:
{
flexDirection: 'row',
},
IconImage: {
paddingLeft: 160,
paddingTop: 45,
},
IconImage2: {
paddingLeft: 160,
paddingTop: 15
},
IconImage3: {
paddingLeft: 70,
paddingTop: 20
},
AddressText: {
paddingLeft: 20,
paddingTop: 20,
fontSize: 16
}
});
Hi how can I first show the user that I've clicked on and then display a swiper ? I can't find a logic for that. I have a list of users and when I click on one, it should open a new component where we will find more infos about that user. Then I want to swipe between the list of users on the same component of the description ?
Here are my user profile component and the flatlist :
render () {
var colorConnected;
if (this.props.navigation.getParam('Statut') === "ON") {
colorConnected = "#1fbc26";
}
else if (this.props.navigation.getParam('Statut') === "OFF") {
colorConnected = "#ff0303";
}
else {
colorConnected = "#ffd200";
}
return (
<Swiper showsPagination={false}>
{this.state.items.map((item, key) => {
return (
<ScrollView style = {styles.view_container}>
<View style={styles.photo}>
<ImageBackground source={{uri:this.props.navigation.getParam('Photo')}} style={{ width: '100%', height: '100%' }}>
<View style={styles.photo_content}>
<LinearGradient colors={['transparent', 'rgba(0,0,0,0.5)']} style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 80 }} />
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View>
<Text style={{ fontSize: 40, color:'white' }}>{this.props.navigation.getParam('Age')}</Text>
</View>
<View style={{ marginRight: 7, marginLeft: 7, backgroundColor: '#ffffff', width: 1, height: 39 }}></View>
<View style={{ flexDirection: 'column', flex:1 }}>
<View style={{ flexDirection: 'row' }}>
<View style={[styles.bulle_presence, { backgroundColor: colorConnected } ]}></View>
<Text style={{ fontSize: 18, fontWeight: '600', color:'white' }}>{this.props.navigation.getParam('Pseudo')}</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{ fontSize: 15, color:'white' }}>{this.props.navigation.getParam('Distance')}</Text>
<Text style={{ fontSize: 15, color:'white'}}>{this.props.navigation.getParam('Genre')}</Text>
</View>
</View>
</View>
</View>
</ImageBackgroud>
</View>
</ScrollView>
)
})}
</Swiper>
)}
}
render() {
GLOBAL.data = this.state.dataSource;
//console.log(GLOBAL.data);
return (
<SafeAreaView style={{ flex:1 }}>
<View style={styles.main_container}>
<FlatList style={styles.flatList}
data={this.state.dataSource}
extraData = {this.state}
keyExtractor={(item, index) => item.MembreId}
renderItem={(item) => <UserItem user={item} displayDetailForUser={this._displayDetailForUser} />}
numColumns={numColumns}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh} />
</View>
</SafeAreaView>
)
}
With this code, I'm only able to swipe on the user where I've clicked. The others user are not showing.
You can open a modal then use a carousel like react-native-snap-carousel in full screen mode to generate your use case
I'm trying to work on this Instagram layout using React Native:
However, I'm unable to arrange the layout properly. Here is my code:
import React from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import StatusBarBackground from './StatusBarBackground';
export default class App extends React.Component {
render() {
return (
<View>
<StatusBarBackground />
<View style={styles.user_profile}>
<View style={styles.container}>
<Image style={styles.image} source={require('./images/user_profile.jpg')}/>
</View>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.container}>
<Text style={styles.numbers}>128</Text>
<Text style={styles.grey_text}>posts</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>256</Text>
<Text style={styles.grey_text}>followers</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>184</Text>
<Text style={styles.grey_text}>following</Text>
</View>
</View>
<View style={styles.btnContainer}>
<Button title="Edit Profile" color="#000" backgroundColor="#CCC" raised={true} onPress={this.onPressEditProfile} />
</View>
</View>
</View>
);
}
onPressEditProfile(event) {
console.log('Clicked Edit Profile');
}
}
const styles = StyleSheet.create({
user_profile: {
width: '100%',
height: 120,
alignItems: 'flex-start',
flexDirection: 'row',
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
image: {
height: 100,
borderRadius: 50,
width: 100,
margin: 10,
alignItems: 'center',
justifyContent: 'center',
},
grey_text: {
color: '#999',
},
numbers: {
fontWeight: 'bold',
},
btnContainer: {
backgroundColor: '#CCC',
borderRadius: 10,
padding: 10,
},
});
It looks like this now:
What did I miss in the layout?
You just applied flexDirection: 'row' to common container so it was cause of your result layout.
I've provided some pseudocode just for your understanding.
const style = StyleSheet.create({
container: {},
infoTopRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
infoBottomRow: {
justifyContent: 'center',
alignItems: 'center',
},
});
<View style={...}>
<Avatar/>
<View style={...}> {/* <---- here should be flexDirection: 'column' or just don't set any value for it */}
<View style={style.infoTopRow}>
<InfoBlock title="posts" value="128" />
<InfoBlock title="followers" value="256" />
<InfoBlock title="following" value="184" />
</View>
<View>
<Button title="Edit Profile" />
</View>
</View>
</View>
You are missing one more wrapper column view
<View>
<StatusBarBackground />
<View style={styles.user_profile}>
//Make this container something like flex:0.2
<View style={styles.container}>
<Image style={styles.image} source={require('./images/user_profile.jpg')}/>
</View>
// You need another column view wrapper
<View style={{flex:0.8}}>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.container}>
<Text style={styles.numbers}>128</Text>
<Text style={styles.grey_text}>posts</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>256</Text>
<Text style={styles.grey_text}>followers</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>184</Text>
<Text style={styles.grey_text}>following</Text>
</View>
</View>
<View style={styles.btnContainer}>
<Button title="Edit Profile" color="#000" backgroundColor="#CCC" raised={true} onPress={this.onPressEditProfile} />
</View>
</View>
</View>
</View>