React-native locked view - css

I would like to make a view that is blurred for non-subscribers to my application, with a lock, when we click we are redirected to the subscription page.
For subscribers I want the view to be visible without any filters.
I don't know how to set up a blurry view above my current view.
Can I do it only with CSS?
I saw the Animated package and react-native-blur but I am not sure of the relevance in my case.
I hope my question is clear and that you can help me. In any case, thank you for reading me.
I have this :
<View style={styles.statContainer}>
<ImageBackground
source={require("../../assets/images/stats-background-5.png")}
style={styles.statImage}
>
<Image
source={require("../../assets/images/lock.png")}
style={{
height: 30,
width: 30,
justifyContent: "flex-start",
alignItems: "flex-start",
}}
></Image>
<Text style={styles.statText}>
{i18n.t("stats.action.countries")}
{"\n"}
<AnimateNumber
value={this.state.stats.countries}
countBy={(
this.state.stats.countries / this.state.animateCountBy +
1
).toFixed(0)}
style={styles.statTextData}
/>{" "}
<Text
style={[styles.textimg, styles.measure]}
onLayout={this.handleLayout}
></Text>
</Text>
</ImageBackground>
</View>
Styles :
statContainer: {
flex: 1,
backgroundColor: "transparent",
marginVertical: 15,
justifyContent: "center",
alignItems: "center",
},
statText: {
fontFamily: "FunctionLH",
color: "white",
fontSize: 20,
paddingVertical: 5,
textAlign: "center",
alignItems: "center",
textShadowColor: "rgba(0, 0, 0, 0.90)",
textShadowOffset: { width: -1, height: 1 },
textShadowRadius: 10,
},
statTextData: {
fontSize: 40,
lineHeight: 50,
paddingVertical: 5,
textAlign: "center",
alignItems: "center",
},
statImage: {
height: 100,
width: "100%",
position: "relative", // because it's parent
justifyContent: "center",
alignItems: "center",
},

If i understood you correctly and you want to blur the image, you can use the blurRadius prop for your Image component:
<Image
source={require("../../assets/images/lock.png")}
blurRadius={5}
style={{
height: 30,
width: 30,
justifyContent: "flex-start",
alignItems: "flex-start",
}}
></Image>

Related

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.

Center react native view

I'm creating a component to show the flag and country name. I'll like that view (image + text) centered in the available space.
So if the width of parent is all the screen, there will be space in the left and same in the right. If the parent is only 50% of the screen will be then left space on the sides...
What I've done:
<View style={styles.mainContainer} >
<View >
<TouchableOpacity
disabled={this.props.disablePicker}
onPress={() => this.setState({ modalVisible: true, dataSource: this.props.dataSource })}
activeOpacity={0.7}
>
<View>
<View style={[pickerStyle,{ flexDirection:'row'}]} >
<Image style={{}} source={selectedLabel.image} />
<Text style={}>{selectedLabel.name}</Text>
{dropDownImage ? <Image
style={dropDownImageStyle}
resizeMode="contain"
source={dropDownImage}
/> : null}
</View>
</View>
</TouchableOpacity>
</View>
</View>
const CountryPickerStyles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
itemSeparatorStyle:{
height: 1,
width: "90%",
alignSelf: "center",
backgroundColor: "#D3D3D3"
},
searchBarContainerStyle: {
marginBottom: 10,
flexDirection: "row",
height: 40,
shadowOpacity: 1.0,
shadowRadius: 5,
shadowOffset: {
width: 1,
height: 1
},
backgroundColor: "rgba(255,255,255,1)",
shadowColor: "#d3d3d3",
borderRadius: 10,
elevation: 3,
marginLeft: 10,
marginRight: 10
},
selectLabelTextStyle: {
color: "#000",
fontSize:16,
flexDirection: "row",
marginLeft: 100,
marginRight: 100
},
placeHolderTextStyle: {
color: "#757575",
padding: 10,
textAlign: "left",
width: "99%",
fontStyle: 'italic',
fontSize:12,
flexDirection: "row"
},
dropDownImageStyle: {
marginLeft: 10,
color: "#757575",
width: 10,
height: 10,
alignSelf: "center"
},
listTextViewStyle: {
color: "#000",
alignItems: "center",
justifyContent: "center",
marginLeft: 20,
marginHorizontal: 10,
textAlign: "left"
},
pickerStyle: {
elevation:0,
paddingRight: 10,
paddingLeft: 10,
marginRight: 10,
marginLeft: 10,
width:"90%",
borderWidth:0 ,
flexDirection: "row"
}
});
here's what I got:
https://pasteboard.co/JG5Rx9P.png
and also https://pasteboard.co/JG5Tthie.png

Enable overflow in native-base cards

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

TextInput going to middle of page

I have a TextInput in my app.js , but it stays in the middle of the page, But I want it to be on the top of the page, I mean just under the notification bar, Please how can I do this
<View style={BackStyles.container}>
<TextInput
underlineColorAndroid={'transparent'} style={BackStyles.textBox}
/></View>
const BackStyles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
flex: 1,
backgroundColor: '#E2E2E2',
marginTop: 20,
},
textBox: {
height: 36,
padding: 4,
marginRight: 5,
flexGrow: 1,
fontSize: 18,
color: '#48BBEC',
backgroundColor: '#fff'
}
});
Try replacing alignItems: 'center' with alignItems: 'flex-start'.

React Native and Flexbox Views

I'm trying to have a TouchableHighlight + View above this list of generated comments. I can't seem to bring the start of the comments closer up to where the TouchableHighlight ends (it ends right after the text, no padding/margin below).
Here's the relevant JSX:
renderListView: function() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this.onSelect}>
<View style={styles.header}>
<Text style={styles.text}>
Visit Site
</Text>
</View>
</TouchableHighlight>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderCommentCell}
style={styles.commentListView} />
</View>
)
},
And here's my styles.js:
container: {
flex: 1,
marginTop: 65,
backgroundColor: '#FFFFFD',
flexDirection: 'column',
},
commentListView:{
margin: 0,
marginTop: 10,
marginRight: 15,
padding: 0,
backgroundColor: '#FFFFFD',
},
centering: {
alignItems: 'center',
justifyContent: 'center',
height: 80
},
header: {
alignItems: 'center',
flexDirection: 'row',
flex: 1
},
loadingText: {
fontSize: 75,
textAlign: 'center',
marginTop: 75,
marginBottom: 10,
marginRight: 10,
color: '#D6573D'
},
text: {
textAlign: 'center',
flexDirection: 'row',
justifyContent: 'center',
alignSelf: 'stretch',
fontSize: 40,
flex: 1
}
Additionally, here's a screenshot of what I'm seeing:
Add automaticallyAdjustContentInsets={false} to your ListView

Resources