Enable overflow in native-base cards - css

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

Related

How to move an element to bottom of div

I am trying to implement waves image at the bottom of the screen as shown in image below. I have tried alignSelf:'flex-end' but it does not work. If i give top with dimensions then if screen size change image top also change. how to implement waves image at the perfect bottom?
I have also tried svg but could not make it work.
Here is my code
import React from 'react';
import {
View,
Text,
Dimensions,
TextInput,
StyleSheet,
Image,
} from 'react-native';
import database from '#react-native-firebase/database';
import auth from '#react-native-firebase/auth';
import Otp from '../assets/otp.svg';
import Waves from '../assets/waves.svg';
import {Icon} from 'native-base';
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const Login = () => {
return (
<View style={styles.container}>
<View style={styles.view1}>
<View style={styles.header}>
<Icon type="AntDesign" name="arrowleft" style={styles.icon} />
<View style={styles.headerView}>
<Text style={styles.headerText}>OTP Verification</Text>
</View>
</View>
<Otp width={250} height={130} style={{top: -40}} />
</View>
<View style={styles.view2}>
<View style={styles.mainDiv}>
<View style={styles.loginForm}></View>
<View style={styles.iconDiv}></View>
</View>
<View style={styles.waves}>
{/* <Waves /> */}
<Image
style={styles.wavesImg}
source={require('../assets/waves.png')}
/>
</View>
</View>
</View>
);
};
export default Login;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'red',
},
view1: {
flex: 1,
backgroundColor: '#e69545',
alignItems: 'center',
justifyContent: 'space-around',
},
view2: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
},
header: {
// backgroundColor: 'red',
flexDirection: 'row',
justifyContent: 'space-around',
},
headerView: {alignItems: 'center', width: '80%'},
headerText: {color: '#fff', fontSize: 27},
icon: {
color: '#fff',
// width: 40,
fontSize: 35,
},
mainDiv: {
backgroundColor: '#fff',
width: (windowWidth / 10) * 8,
height: (windowHeight / 100) * 40,
position: 'absolute',
borderRadius: 25,
top: -60,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.3,
shadowRadius: 4.65,
elevation: 8,
},
waves: {
// // height: 300,
// position: 'absolute',
// bottom: 0,
// backgroundColor: 'green',
// position: 'absolute',
// top: (windowHeight / 10) * 3.1,
width: '100%',
height: 130,
// alignSelf: 'flex-end',
marginTop: (windowHeight / 10) * 3,
},
wavesImg: {
width: '100%',
height: 130,
},
});
I think you should try to put the style for the waves like this:
waves: {
height: 130,
width: windowWidth,
bottom: 0,
position: 'absolute'
}

React Native translate text with percentage values not working

I have a react native project where I want to orientate a element verticaly and center the text.
Now I want to use percentages so it is centered width wise which would be the height of the parent element. Also the text should wrap it gets to big.
The problem is I can not use percentage because it get always converted to px inside the browser.
Can someone help me out?
I appreciate your help.
The text on the left side should always be centered like it is in this screenshot. It behaves so weird, if the width is changing the text moves around.
type TeamsProps = {
name: string,
}
const TeamCard = (props: TeamsProps) => {
const [showOptions, setShowOptions] = useState<Boolean>(false)
const toggleOptions = () => {
setShowOptions(!showOptions)
}
return (
<View style={[styles.container, { height: (Dimensions.get("window").width - 3 * 15) / 2 }]}>
<TouchableOpacity onLongPress={toggleOptions} style={styles.card}>
<View style={styles.nameFlag}>
<Text style={styles.name}>{props.name}</Text>
</View>
<View style={styles.member}>
</View>
</TouchableOpacity>
{ showOptions ?
<TouchableOpacity onPress={toggleOptions} style={styles.options}>
<TextInput style={styles.input} value="Team Name"></TextInput>
<View style={styles.buttons}>
<TouchableOpacity style={[styles.button, styles.delete]}>
<Delete style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.confirm]}>
<Check style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
</View>
</TouchableOpacity>
: <></>
}
</View>
)
}
const styles = StyleSheet.create({
container: {
flexBasis: "calc(50% - 7.5px)"
},
card: {
backgroundColor: constants.mainColor,
borderRadius: 15,
shadowOpacity: 0.6,
shadowRadius: 10,
flex: 1,
flexDirection: "row",
alignItems: "center"
},
nameFlag: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "15%",
marginVertical: 15,
borderTopRightRadius: 30,
borderBottomRightRadius: 30,
justifyContent: "center"
},
name: {
position: "absolute",
// TODO: translateX needs to use -50%, translateY needs to use 50% of parent width
transform: [{ rotate: "-90deg" }, { translateX: -33 }, { translateY: 13 }],
transformOrigin: "left",
width: "max-content",
fontFamily: constants.fontFamilyHeader,
fontSize: constants.fontSizeHeader
},
member: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "calc(85% - 30px)",
margin: 15,
borderRadius: 30,
padding: 15,
flex: 1,
flexDirection: "row",
flexWrap: "wrap",
gap: 15,
justifyContent: "space-around",
alignItems: "center"
},
options: {
backgroundColor: constants.shadowColor,
position: "absolute",
top: 0,
left: 0,
zIndex: 100,
width: "100%",
height: "100%",
borderRadius: 15,
padding: 15,
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: 25
},
input: {
backgroundColor: "white",
width: "100%",
borderRadius: 50,
padding: 5,
fontFamily: constants.fontFamilySubheader,
fontSize: constants.fontSizeHeader,
textAlign: "center"
},
buttons: {
flexDirection: "row",
gap: 25
},
button: {
borderRadius: 50,
width: 40,
height: 40
},
delete: {
backgroundColor: constants.alertColor
},
confirm: {
backgroundColor: constants.accentColor
}
})
Return to post

Flexbox styling with React Native

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.

How to get rounded image tag on top of two div in react native?

I want to create a profile page where rounded image will be on top of two div in 30:70 ratio where top div will be empty and bottom div will contain few items. I have tried few code snippets from web.
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: 'green', justifyContent: 'flex-start', alignItems: 'flex-start' }}>
<View style={{ flexDirection: 'column', justifyContent: "flex-start", alignItems: "flex-start", alignSelf: "flex-start" }}>
{/* <View style={{ flex: 1, flexDirection: 'row', alignItems: 'flex-end', alignSelf: 'flex-start', margin: 1 }}> */}
<View style={{ backgroundColor: 'white', borderRadius: 10, flexDirection: 'column', height: "30%", width: "100%" }}></View>
{/* </View> */}
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'flex-start', alignSelf: 'flex-start', margin: 1 }}>
<View style={{ backgroundColor: 'white', borderRadius: 10, flexDirection: 'column', height: "70%", width: "100%" }}></View>
</View>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center', alignSelf: 'center', position: 'absolute' }}>
<View style={{
backgroundColor: 'blue',
borderRadius: 10, height: 100, width: 100, borderRadius: 100 / 2
}}></View>
</View>
</View>
reference image
Taking as reference the image you share with us... You can have two views and set the profile avatar style to:
{
position: 'absolute',
alignSelf: 'center',
etc..
}
Check a quick demo: https://snack.expo.io/#abranhe/avatar-example
App.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, ImageBackground, Image } from 'react-native';
import { Ionicons, FontAwesome } from '#expo/vector-icons';
import Constants from 'expo-constants';
import { avatar, background } from './data';
export default class App extends Component {
renderRow({ action, icon, fontAwesome = false }) {
return (
<View style={styles.actionRow}>
{fontAwesome
? <FontAwesome name={icon} size={25} />
: <Ionicons name={icon} size={32} />}
<Text style={styles.text}>{action}</Text>
</View>
);
}
render() {
return (
<View style={styles.container}>
<ImageBackground source={background} style={styles.background}>
<Image source={avatar} style={styles.avatar} />
</ImageBackground>
<View style={styles.content}>
{this.renderRow({ action: 'Scanner', icon: 'ios-camera' })}
{this.renderRow({
action: 'Profile',
icon: 'user-circle-o',
fontAwesome: true,
})}
</View>
</View>
);
}
}
You styles:
const styles = StyleSheet.create({
container: {
flex: 1,
},
background: {
width: '100%',
height: 130,
},
content: {
flex: 1,
marginTop: 80,
marginHorizontal: 10,
},
avatar: {
width: 100,
height: 100,
borderRadius: '50%',
borderWidth: 0.7,
borderColor: 'black',
position: 'absolute',
alignSelf: 'center',
marginTop: 80,
},
actionRow: {
width: '100%',
height: '50',
flexDirection: 'row',
alignItems: 'center',
margin: 10,
},
text: {
marginLeft: 15,
fontWeight: '500',
},
});

react-native scrollView is not properly woking for me

i have tries so many times but when usting different component in scroll body it just not adjust on to the content therefor some content are not included in scrollView. it has cut as shown as in the image..any sugession for fix..?
sample code i used
const height = Dimensions.get('window').height;
const width = Dimensions.get('window').width;
some code in the class
<ScrollView>
<View style={styles.middleview}>
<TextInput
style={styles.textinputs}
placeholder="Location"
placeholderTextColor='grey'
/>
<TouchableOpacity>
<Text style={{fontSize:20}}>
Post Ad
</Text>
</TouchableOpacity>
</view>
</scrollView>
styles used
textinputs: {
backgroundColor: 'white',
paddingTop: '2%',
paddingBottom: '2%',
paddingLeft: '4%',
paddingRight: '4%',
width: '90%',
borderRadius: 50,
margin: '3%',
color: 'grey',
height: '8%',
borderColor: 'white',
borderWidth: .8,
elevation: 10,
middleview:{
backgroundColor: 'lightblue',
flex: 1,
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
alignItems: 'center',
justifyContent: 'center'
}
here is the image below its cut the component scroll view is ended in the middle of components..
Add style to the scrollview using "contentContainerStyle"
Working eg: https://snack.expo.io/#msbot01/rebellious-cookie

Resources