I'm trying to make a slider animation, like the one you get when you power off iOS on iPhones. This is what I have so far and it is self-contained.
import {PanResponder, View, Text, Dimension} from 'react-native';
const {width} = Dimension.get('window');
const TOTAL_WIDTH = width - 50;
class slider extends React.Component {
t = <Text>Slide to Export & Delete</Text>;
state = {
button_translate_x: 0
};
move_right(event, dx) {
if (dx > 0 && event.nativeEvent.pageX <= TOTAL_WIDTH) {
if (dx === width - 50) {
this.setState({button_translate_x: 0});
} else {
this.setState({button_translate_x: dx});
}
}
}
release_handler(e, gs) {
const diff = Math.abs(e.nativeEvent.pageX - TOTAL_WIDTH);
if (diff <= 5) {
this.setState({button_translate_x: gs.dx});
} else {
this.setState({button_translate_x: 0});
}
}
pan_responder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, gestureState) => {
this.move_right(evt, gestureState.dx);
},
onPanResponderRelease: (evt, gestureState) => {
this.release_handler(evt, gestureState);
}
});
smoothing_margin() {
if (this.state.button_translate_x <= 25)
return Math.abs(this.state.button_translate_x - 20);
else return 0;
}
render() {
return (
<View style={{alignItems: 'center'}}>
<View
style={{
alignItems: 'center',
borderRadius: 25,
width: TOTAL_WIDTH,
backgroundColor: 'orange'
}}>
<View
style={{
width: this.state.button_translate_x,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
backgroundColor: 'blue',
borderRadius: 25,
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -1,
marginVertical: this.smoothing_margin()
}}
/>
<View
style={{
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -2
}}>
{this.t}
</View>
<View
style={{
alignSelf: 'flex-start',
width: 50,
transform: [{translateX: this.state.button_translate_x}],
height: 50,
borderRadius: 25,
backgroundColor: 'red'
}}
{...this.pan_responder.panHandlers}
/>
</View>
</View>
);
}
}
But this is wrong though because the initial slide has the blue coming out of the rounded bounds of the orange view. I have tried to be clever with this with marginVertical but not sure if that is the correct way to go about it.
Sliding all the way to the right is incorrect because the blue should be covering at least to the middle of the circle but as currently written only goes up to the left side.
Help appreciated.
Figured it out!
import {PanResponder} from 'react-native';
const TOTAL_WIDTH = width - 50;
class slider extends React.Component {
t = <Text>Slide to Export & Delete</Text>;
state = {button_translate_x: 0};
pan_responder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, {dx}) => {
if (dx > 0 && TOTAL_WIDTH - 50 >= dx) {
this.setState({button_translate_x: dx});
}
},
onPanResponderRelease: ({nativeEvent: {pageX}}, {dx}) => {
if (TOTAL_WIDTH - 50 - dx <= 5) {
console.log('Success zone');
} else {
this.setState({button_translate_x: 0});
}
}
});
render() {
return (
<View style={{alignItems: 'center'}}>
<View
style={{
alignItems: 'center',
borderRadius: 25,
width: TOTAL_WIDTH,
backgroundColor: 'orange'
}}>
<View
style={{
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -2
}}>
{this.t}
</View>
<View
style={{
alignSelf: 'flex-start',
width: 50,
transform: [{translateX: this.state.button_translate_x}],
height: 50,
borderRadius: 25,
backgroundColor: 'red'
}}
{...this.pan_responder.panHandlers}
/>
<View
style={{
borderRadius: 25,
position: 'absolute',
top: 0,
bottom: 0,
right: 0,
left: 0,
backgroundColor: 'blue',
height: 50,
width: this.state.button_translate_x + 50,
zIndex: -1
}}
/>
</View>
</View>
);
}
}
Related
I'm trying to fit my background image to cover the whole app but its not, even though i've tested most of similar threads here so any help is appreciated.
I've made some changes to the original source and added an arrow towards the left edge of the image that i was hoping to have at the edge when i open up the EXPO app on my phone, but i only see a few pixels of the arrow at the left edge.
**app.js**
function HomeScreen() {
return (
<ImageBackground source={require('./assets/bgImage.jpg')} style={styles.bgImage}>
<View>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
bgImage: {
flex: 1,
width: null,
height: null,
resizeMode: 'cover',
justifyContent: 'center',
alignItems: "center"
}
try this :-
import React from 'react';
import { ImageBackground, View, Text } from 'react-native';
const HomeScreen = () => {
return (
<ImageBackground source={require('../assets/apple.jpg')}
style={{
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
flex: 1,
alignItems: "center"
}}>
<View style={{
width: '90%',
height: 200,
backgroundColor: "red",
justifyContent: "center",
alignItems: "center",
}}>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
export default HomeScreen;
It is working fine.
I am using tcomb-form-native version 0.6.15 for form validation in react-native Version0.55.4 . When I use password field text should be hidden inside dots. As per docs I used secureTextEntry and set it to true but it is still showing the data like a simple text. I found some suggestion to use temple but i don't know how to use them.
Below is the Form code
const Form = t.form.Form;
t.form.Form.stylesheet.controlLabel.normal = {color: 'white'}
console.log(t.form.Form.options)
const User = t.struct({
name: t.String,
email: t.String,
password: t.String,
});
const formStyles = {
...Form.stylesheet,
formGroup: {
normal: {
marginBottom: 10,
color: 'white'
},
},
controlLabel: {
normal: {
fontSize: 12,
marginBottom: 7,
fontWeight: '600',
},
// the style applied when a validation error occours
error: {
color: 'red',
fontSize: 18,
marginBottom: 7,
fontWeight: '600',
},
},
};
const options = {
order: ['name', 'email', 'password' ],
fields: {
name: {
placeholder: 'Enter Name',
error: 'Name is empty?',
},
email: {
placeholder: 'Enter Email',
error: 'Email is empty?',
},
password: {
placeholder: 'Enter Password',
error: 'Password is empty?',
secureTextEntry: true,
template: (locals) => textbox(locals, )//here i can use template but don't know how
},
},
stylesheet: formStyles,
};
class SignupScreen extends Component{
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
password: '',
dateOfBirth: '',
};
}
onSubmit(){
const value = this._form.getValue();
console.log('value: ', value);
}
render(){
console.log(this.state.dateOfBirth)
return(
<ImageBackground
source={require('../../images/splash_screen.jpg')}
style={{flex: 1}}
>
<View style={styles.container}>
<View style={{flex:3, justifyContent: 'center', alignItems: 'center'}}>
<Image source={require('../../images/big_transparent_logo.png')} />
<Text style={styles.subtitleStyle}>Get free drink everyday</Text>
</View>
<View style={{ flex: 7, justifyContent: 'flex-start', alignSelf: 'center', alignItems: 'center', width: '80%'}}>
<View style={{width: '100%', paddingHorizontal: 10, paddingVertical: 10 , backgroundColor: 'rgba(0,0,0,0.6)'}}>
<Form ref={c => (this._form = c)} type={User} />
<TouchableOpacity style={{width: '100%', marginVertical: 10}} >
<Label title="BIRTHDAY" />
<DatePicker
style={{width: '100%'}}
date=''
mode="date"
placeholder={this.state.dateOfBirth}
format="DD-MM-YYYY"
maxDate="2002-06-01"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
showIcon={true}
androidMode='spinner'
customStyles={{
dateInput: {
marginLeft: 0,
borderWidth: 0,
textAlign: 'left',
color: 'white',
backgroundColor: '#f2f2f2',
paddingVertical: 0,
height: 30,
color: 'black'
}
// ... You can check the source to find the other keys.
}}
onDateChange={(date) => {this.setState({dateOfBirth: date})}}
/>
</TouchableOpacity >
<Button block bordered light
style={{ width: '47%', borderRadius: 5, alignSelf: 'center', height: 50}}
onPress={this.onSubmit.bind(this)}
>
<Text style={{color: 'white'}}>Sign Up</Text>
</Button>
<Button block light
style={{ width: '47%', borderRadius: 5, alignSelf: 'center', height: 50, backgroundColor: 'rgba(0,0,0,0)',}}
onPress={()=>this.props.navigation.goBack()}
>
<Text style={{color: 'white'}}>Back</Text>
</Button>
</View>
</View>
</View>
</ImageBackground>
);
}
}
export { SignupScreen };
Your form is not connected to the options variable. Call options in your form tag as in below.
<Form ref={c => (this._form = c)}
type={User}
options={options} //set form options
/>
It should work without a template.
password: {
password: true,
secureTextEntry: true}
}
I'm trying to overlap elements as shown in the wireframe, as well as position them.
I've tried
- position: 'relative' and the element disappears
- position: 'absolute' but alignItems: 'center' does nothing
Can anyone help identify what's missing?
Wireframe of Wishlist (ignore the different header; it was from an old version)
This is what I get instead, even after using flex
I've attached code from all the separate .js files, and left out all import and export statements.
Thank you!
----------- in WishlistDetail.js------------
// Each Item on The Wishlist
const WishlistDetail = () => {
return (
<View>
<WishlistCard>
<WishlistThumbnail />
<WishlistThumbnailFilter />
<WishlistPrice />
<WishlistItemDetail />
</WishlistCard>
</View>
);
};
---------- in WishlistCard.js------------------
// Creating WishlistCard
const WishlistCard = (props) => {
return (
<View style={styles.containerStyle}>
{props.children}
</View>
);
};
// WishlistCard Style
const styles = StyleSheet.create({
containerStyle: {
borderWidth: 0.75,
backgroundColor: 'white',
borderColor: 'rgb(217, 217, 217)',
height: 125 // ******* not too sure
}
});
---------- in WishlistThumbnail.js------------------
const WishlistThumbnail = () => {
const { wishlistThumbnailStyle } = styles;
return (
<View>
<Image
style={wishlistThumbnailStyle}
source={{ uri: 'http://www.startwire.com/job-applications/logos/amazon.png' }}
/>
</View>
);
};
// All Styling
const styles = StyleSheet.create({
wishlistThumbnailStyle: {
height: 95,
width: 95,
padding: 20,
position: 'absolute',
justifyContent: 'center'
}
});
---------- in WishlistThumbnailFilter.js------------------
// Creating Wishlist Thumbnail Filter
const WishlistThumbnailFilter = () => {
return (
<View style={styles.wishlistThumbnailFilterStyle} />
);
};
// Image Filter Style - 146 125 192.2
const styles = StyleSheet.create({
wishlistThumbnailFilterStyle: {
width: 160,
borderTopColor: 'rgba(13, 13, 13, 0.05)',
borderLeftColor: 'transparent',
borderRightColor: 'transparent',
borderTopWidth: 250,
borderLeftWidth: 0,
borderRightWidth: 90
}
});
---------- in WishlistPrice.js------------------
const WishlistPrice = () => {
const { textStyle, viewStyle } = styles;
return (
//INSERT PRICE HERE
<View style={viewStyle}>
<Text style={textStyle}>30€</Text>
</View>
);
};
// Wishlist Price Style
const styles = StyleSheet.create({
viewStyle: {
backgroundColor: 'transparent',
padding: '3',
// alignItems: 'flex-end',
justifyContent: 'flex-end',
position: 'absolute'
// position: 'relative'
},
textStyle: {
fontSize: 11.5,
fontFamily: 'Bariol_Regular',
color: 'rgb(127, 127, 127)'
}
});
---------- in WishlistItemDetail.js------------------
// This contains both Wishlist Title and Wishlist Text
const WishlistItemDetail = () => {
const { wishlistItemDetailStyle, wishlistItemTitleStyle, wishlistItemTextStyle } = styles;
return (
<View style={wishlistItemDetailStyle}>
<Text style={wishlistItemTitleStyle}>Wishlist Item Title</Text>
<Text style={wishlistItemTextStyle}>Wishlist Item Text</Text>
</View>
);
};
// Header Style
const styles = StyleSheet.create({
wishlistItemDetailStyle: {
backgroundColor: 'transparent',
position: 'absolute',
padding: 5
},
wishlistItemTitleStyle: {
fontSize: 15,
fontFamily: 'Bariol_Regular',
color: 'rgb(51, 51, 51)'
},
wishlistItemTextStyle: {
fontSize: 12,
fontFamily: 'Bariol_Regular',
color: 'rgb(70, 70, 70)'
}
});
without wanting to go into too much detail, this seems to look like an issue of column vs row in you flexDirection.
In order to get the style of the wireframe you provided you need to use a combination of both row and column. Check out this documentation: https://facebook.github.io/react-native/docs/flexbox.html
So one row consists of two main views styled in a flexrow and the one I marked blue is styled in a column (which is the default).
Hope this helps
React Native Animation does not scale. Animation is bigger. My code:
import { DangerZone } from 'expo';
const { Lottie } = DangerZone;
Styles:
animationContainer: {
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',z
},
View:
<Lottie
ref={(animation) => {
this.animation = animation;
}}
resizeMode="contain"
loop={Boolean(true)}
style={{
width: 300,
height: 30,
backgroundColor: '#ccc',
}}
source={this.state.animation}
/>
App screenshot
I don`t know why this does not work. Please help me
I'm developing an app with React-Native.
I want to put an icon on right-bottom corner of an image component, but it always stays on the left-top corner.
Any help? Thank you very much.
<Image source={imageSource} style={{position: "absolute", bottom: 0, right: 0}}/>
You can use justifyContent: 'flex-end' to achieve this:
const withWatermark = (asset, logo) => (
<Image style={{ width: 200, height: 200, justifyContent: 'flex-end' }} source={asset}>
<Image style={{ width: 20, height: 20, alignSelf: 'flex-end' }} source={logo} />
</Image>
);
You can do something like this...
Use this : position: "absolute", bottom: 0, alignSelf: "flex-end"
<ImageBackground
source={require("../assets/homeAssets/3.jpg")}
style={{
height: 140,
width: 140,
resizeMode: "contain",
alignItems: "center"
}}
imageStyle={{ borderRadius: 70 }}
>
<View
style={{
height: 50,
width: 50,
borderRadius: 25,
backgroundColor: "#99AAAB",
alignItems: "center",
justifyContent: "center",
position: "absolute", //Here is the trick
bottom: 0,
alignSelf: "flex-end"
}}
>
<Entypo name="camera" size={25} color="#FFF" />
</View>
</ImageBackground>