Related
I am implementing a tile in reactnative and I have to make the Image right in the tile just like this
What I want (click here)
and this is what I can implement till now
What I get ()
this is my code
<View style={styles.container} >
<Image
style={styles.image}
source={item.image}
resizeMode="cover"
/>
<View style={styles.overlay} />
<View style={styles.textContainer}>
<Text style={styles.subText}>{item.title}</Text>
<Text style={styles.headingText}>{item.message}</Text>
</View>
</View>
and this is style
const styles = StyleSheet.create({
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end',
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
marginTop: 20
},
image: {
width: COURSE_ITEM_WIDTH,
height: 120,
borderRadius: 10
},
textContainer: {
position: 'absolute',
left: 16,
flex: 1,
},
headingText: {
fontSize: 18,
color: '#ffffff',
marginTop: 5
},
subText: {
fontSize: 14,
color: '#ffffff',
},
timeText: {
fontSize: 15,
color: 'white',
textAlign: 'center',
marginTop: 5
},
overlay: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: '#206c72',
opacity: 0.6,
borderRadius: 10
}
})
Please help me i dont know what i am doing wrong. thanks in advance!
[note: please ignore the content, focus on alignment]
Your image is aligned to the right but there is nothing at the left of it. You should add flexDirection:'row' to the parent container and put an empty View with width : 40px before your image.
You can also remove the alignItems:flex-end and justifyContent:center from the main container
You can add alignSelf property to flex-end for image and image will be on end of the tile.
example 1:
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
alignSelf: "flex-end"
},
for reference i tried a sandbox example check it out here
also noticed you are using alignItems value twice first one is only necessary you can remove 2nd alignItems and position relative value from styles.container then it will align the image to end. you will get the exact result you want
example 2:
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end', // only need this alignItems
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
marginTop: 20
},
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
// no need of alignSelf to flex-end here
},
I'm new at react native development, I want to make a card with a semi circle like this:
I tried something with :
borderRadius:'45%',
bottom:10,
right:10,
And get that this result, but isn't what I need
You can do this works
<View style={{
width: '90%',
height: 160,
backgroundColor: 'white',
elevation: 4,
borderRadius: 40,
overflow: 'hidden',
alignSelf: 'center'
}}>
<View style={{
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
borderBottomRightRadius: 80,
borderTopRightRadius: 80,
backgroundColor: '#f29a50',
elevation: 4,
}}>
{/* Your Icon */}
</View>
</View>
[1]: https://i.stack.imgur.com/4tcEh.png
Putting overflow: "hidden" on the parent View solved the overlay issue.
Well I thought I was getting the hang of styling. Tested on several different sized phones and it all looked great. Then... I tested on an iPad. Several of my screens ran way off the page. I am using flex: 1 for the container so I don't understand why. Do iPads not respect flex: 1 or something? Or did I just royally mangle the layout code? I thought using the screen dimensions and % to calculate most things would work for responsive design.
Example, sign in screen. Bottom 2 buttons "Login" and "Home" run almost completely off iPad screen. On phone devices seem to display fine.
EDIT: Thank you so much for the answer! I have rewritten the code and it looks fabulous now on the ipad. I hope this code is an improvement, I have added it to the bottom. Now to rewrite ALL the screens facepalm
import React, { useState } from "react";
import {
Dimensions,
Image,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { auth } from '../../src/config'
import AppText from "../components/AppText";
import colors from "../config/colors";
import Constants from "expo-constants";
let width = Dimensions.get('window').width;
function SignIn( { navigation } ){
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [message, setMessage] = useState('');
function emailSignIn(email, password){
email = email.trim();
auth.signInWithEmailAndPassword(email, password)
.then(function(result) {
setMessage('');
}).catch(function(error) {
setMessage('Invalid Email or Password. Sorry :(');
});
}
function updateEmail(email){
setMessage('');
setEmail(email);
}
function updatePassword(password){
setMessage('');
setPassword(password);
}
return (
<View style={styles.container}>
<Image style={styles.image} source={require("../assets/logo.png")} />
<Image style={styles.rainbow} source={require("../assets/rainbow.png")} />
<View style={styles.bottom}>
<View style={styles.inputView}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="E m a i l..."
placeholderTextColor="#003f5c"
onChangeText={(email) => updateEmail(email)}
autoCapitalize = 'none'
/>
</View>
<View style={styles.inputView2}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="P a s s w o r d..."
placeholderTextColor="#003f5c"
secureTextEntry={true}
onChangeText={(password) => updatePassword(password)}
autoCapitalize = 'none'
/>
</View>
<TouchableOpacity onPress={()=> navigation.navigate('ForgotPassword')}>
<Text style={styles.forgot_button}>Forgot Password?</Text>
</TouchableOpacity>
<AppText style={styles.message}>{message}</AppText>
<TouchableOpacity onPress={()=>emailSignIn(email,password)} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>navigation.navigate('StartScreen')} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>HOME</Text>
</TouchableOpacity>
</View>
</View>
);
}
export default SignIn;
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
paddingVertical: "3%",
width: width * 0.8,
marginBottom: 10,
},
appButtonText: {
fontSize: width * 0.04,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
bottom: {
alignItems: "center",
marginTop: width * 0.8,
},
container: {
flex: 1,
backgroundColor: colors.white,
justifyContent: "center",
alignItems: "center",
marginTop: Constants.statusBarHeight,
},
forgot_button: {
height: width * 0.1,
fontWeight: "bold",
},
image: {
width: width* 0.5,
resizeMode: "contain",
position: "absolute",
top: -20,
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
marginBottom: width * 0.05,
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
marginBottom: 0,
},
message: {
color: colors.red,
marginTop: width * 0.05,
marginBottom: 10,
alignSelf: "center",
},
rainbow: {
position: "absolute",
top: "10%",
},
});
New styles:
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
justifyContent: "center",
marginHorizontal: "5%",
height: "25%",
},
appButtonText: {
fontSize: 18,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
container: {
flex: 1,
backgroundColor: colors.white,
marginTop: Constants.statusBarHeight,
},
forgot_button: {
alignSelf: "center",
fontWeight: "bold",
},
image: {
height: 200,
width: 200,
},
imageContainer: {
flex: 2,
justifyContent: "center",
alignItems: "center",
},
inputButtons: {
flex: 1,
justifyContent: "space-around",
marginHorizontal: "10%",
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
height: "25%",
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
height: "25%",
},
message: {
color: colors.red,
alignSelf: "center",
},
rainbow: {
flex: 1,
width: "100%",
height: "100%",
position: "absolute",
},
rainbowImage: {
height: "60%",
position: "absolute",
top: "15%",
},
submitButtons: {
flex: 1,
justifyContent: "space-around",
},
});
You're getting a width from Dimensions at the top level of your file and then basing all of your layout calculations on this later on. This means that whenever this file is first parsed/run, that width will be calculated. That'll work if the device reports its width correctly on the first pass through the code (not guaranteed), but will break if it gets an unusual width during that pass (likely) and will definitely break if the window changes size or rotates.
Instead of basing all of your calculations on that static width, I suggest you look into leveraging Flexbox for dynamic layouts.
For example, at one point in your code, you set a TextInput to 80% of the view by doing width * 0.8. You could do the same thing by just setting the width to 80%:
export default function App() {
return (
<View style={{flex: 1, justifyContent: "center", alignItems: "center"}}>
<TextInput
style={{borderWidth: 1, width: "80%"}}
/>
</View>
);
}
Basically, try to do everything you can to get rid of relying on Dimensions unless you really need it. And, if you do need it, make sure you calculate it at the time you need it based on the current screen and not just at the first run of the app.
Making a notification bubble for messages, but text is not centering.
Here is my code:
<View style = {{justifyContent: 'center', alignItems: 'center', position: 'absolute', top: -5, right: 10,
backgroundColor: 'red', height: h, width: w, borderRadius: br}}>
<Text style = {{fontSize: 10, color: 'white', textAlign: 'center'}}>
{'7'}
</Text>
</View>
And here is the result:
Result
Try alignSelf: center in your text style
I have a component in a website that looks like this:
Regular card
It's basically a div with an image inside it, but the image has a margin-top of -50 so that it overflows off the card.
I would like to accomplish the same thing with react-native and native-base. Here is the relevant code:
render() {
return (
<View style={styles.container}>
<Card>
<CardItem style={{ marginTop: -50, justifyContent: 'center' }}>
<Image style={styles.image} source={{ uri: this.state.band.imageComponent.link }} />
</CardItem>
</Card>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 150
},
image: {
width: 150,
height: 150,
)
And the result looks like this:
React-native card
As you can see, the picture is cutoff at the top. How can I keep the image overflow and have it overlay the card like in my first image?
Overflow is not supported in Android. There are lots of open issues for that. Check some of them here and here.
Here's an npm package that apparently solves that issue that you could try.
Otherwise you can use a workaround for that I found on this medium post.
According to your image you have to wrap your image and the container inside another View as siblings and then position them absolutely.
Here's the code that I tweaked a little bit from that post. You can replace the View according to your Card and CardItem styles.
<View style={styles.container}>
<View style={styles.cardSection1}>
<Image style={styles.image} source={{ uri: 'https://imgplaceholder.com/420x320/ff7f7f/333333/fa-image' }} />
</View>
<View style={styles.cardSection2}>
</View>
</View>
const styles = {
container: {
flex: 1,
backgroundColor: 'grey',
alignItems: 'center'
},
image: {
width: 150,
height: 150,
},
cardSection1: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
width: 100,
height: 100,
borderRadius: 50 / 2,
zIndex: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.2,
shadowRadius: 10,
elevation: 7,
},
cardSection2: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 25,
width: 300,
height: 150,
borderRadius: 8,
backgroundColor: 'white',
zIndex: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.2,
shadowRadius: 10,
elevation: 5,
}
}
This is the output that I got.
//import liraries
import React, { Component } from 'react';
import { View, Text, StyleSheet,TextInput,Dimensions,Image } from 'react-native';
import ButtonRoundBorder from '../components/ButtonRoundBorder';
const window = Dimensions.get('window')
// create a component
class Login extends Component {
render() {
return (
<View style={styles.container}>
<Image style={{width:window.width,height:window.height,position:'absolute'}} source={require('../images/bg2.jpeg')}/>
<View style={styles.overlayImageStyle} >
<Image style={{flex:1,borderRadius:80}} resizeMode={'contain'} source={require('../images/profile.jpg')} />
</View>
<View style={styles.cardStyle}>
<View style={styles.insideCard}>
<Text style={{fontWeight:'bold',fontSize:20,alignSelf:'center'}}>Login</Text>
<TextInput style={[styles.textInputStyle,{marginTop:30}]} underlineColorAndroid='#000000' placeholder='Enter Email' />
<TextInput style={[styles.textInputStyle,{marginTop:20}]} underlineColorAndroid='#000000' placeholder='Enter Password' />
<ButtonRoundBorder style={{marginTop:40}} title='Login'/>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
alignItems: 'center',
backgroundColor: 'transparent',
},
overlayImageStyle:{
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
width: 100,
height: 100,
borderRadius: 100/2,
backgroundColor: 'white',
top:50,
shadowColor: '#000',
// position: 'absolute',row
// shadowOpacity: 0.2,
// shadowRadius: 10,
elevation: 7,
},
cardStyle:{
// alignItems: 'center',
// justifyContent: 'center',
// position: 'absolute',
top: 80,
width: window.width - 40,
height: window.height - 200,
borderRadius: 8,
backgroundColor: 'white',
// backgroundColor: '#7E57C2',
shadowColor: '#000',
elevation: 5,
},
insideCard:{
top: 80,
alignContent: 'center',
justifyContent: 'center',
flexDirection:'column',
},
textInputStyle:{
width:300,
height:40,
alignSelf:'center',
}
});
//make this component available to the app
export default Login;
here is the link for screenshot