I try to implement a sliding bar and bond the sliding animation to a TouchableOpacity.
I initialized the parameter as sliderPosition: new Animated.Value(0)
the onPress function is :
onPress: function(event){
Animated.timing(this.state.sliderPosition, {
toValue: 202.5,
duration: 100,
easing: Easing.linear,
}).start();
},
I kept getting this error
[tid:com.facebook.react.RCTExceptionsManagerQueue] Unhandled JS Exception: singleValue.stopTracking is not a function. (In 'singleValue.stopTracking()', 'singleValue.stopTracking' is undefined)
layout for the slider is:
<View style = {styles.sliderContainer}>
<Animated.View style = {[styles.slider, {marginLeft:this.state.sliderPosition}]}>
</Animated.View>
</View>
styles:
sliderContainer: {
position: 'absolute',
top: 138,
left: 0,
right: 0,
height: 5,
backgroundColor: '#E15668',
shadowRadius: 1,
shadowOpacity: 0.5,
shadowColor: 'gray',
shadowOffset: {width: 0, height: 2},
opacity: 0.9
},
slider: {
marginTop: 0,
backgroundColor: '#FCC31B',
width: 120,
height: 5,
},
did I do something wrong?
Are you sure that sliderPosition property on your state remains an instance of Animated.Value? That error you're getting speaks to that being the issue. Here is a complete example using your code snippets that works as you'd expect. Try this out and if the snippet doesn't help solve your issue, please post more of your surrounding code to lend more context:
import React from 'react';
import {
Animated,
AppRegistry,
Easing,
StyleSheet,
Text,
TouchableOpacity,
View
} from 'react-native';
class MyApp extends React.Component {
constructor(props) {
super(props);
this.onPress = this.onPress.bind(this);
this.state = {
sliderPosition: new Animated.Value(0)
}
}
onPress(event){
Animated.timing(this.state.sliderPosition, {
toValue: 202.5,
duration: 100,
easing: Easing.linear,
}).start();
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.onPress}>
<Text>Animate It</Text>
</TouchableOpacity>
<View style = {styles.sliderContainer}>
<Animated.View style = {[styles.slider, {marginLeft:this.state.sliderPosition}]}>
</Animated.View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
sliderContainer: {
position: 'absolute',
top: 138,
left: 0,
right: 0,
height: 5,
backgroundColor: '#E15668',
shadowRadius: 1,
shadowOpacity: 0.5,
shadowColor: 'gray',
shadowOffset: {width: 0, height: 2},
opacity: 0.9
},
slider: {
marginTop: 0,
backgroundColor: '#FCC31B',
width: 120,
height: 5,
}
});
AppRegistry.registerComponent('MyApp', () => MyApp);
Related
I'm new to app development. I want to prepare a different View like the picture below. I tried but I couldn't. When I did the View was not responsive. Is there an easier and more responsive way for me to do this?
I want to do:
My codes:
import React from "react"
import { Dimensions, StyleSheet, View } from "react-native"
const units = {
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
}
export default function Main( ) {
return (
<>
<View
style={styles.container}>
<View style={styles.leftBlock} />
<View style={styles.middleBlock} />
<View style={styles.rightBlock} />
</View>
<View style={styles.circle}/>
</>
)
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
bottom: 0,
flexDirection: 'row',
},
leftBlock:{
height: 50,
width: units.width / 3,
backgroundColor: "black",
borderTopRightRadius: 10
},
middleBlock:{
height: 50,
width: units.width / 3,
backgroundColor: "black",
},
rightBlock:{
height: 50,
width: units.width / 3,
backgroundColor: "black",
borderTopLeftRadius: 10
},
circle:{
position: 'absolute',
width: units.width / 2.5,
height: units.width / 2.5,
backgroundColor: 'white',
bottom: 10,
left: units.width / 3.35,
borderBottomRightRadius: 999,
borderBottomLeftRadius: 999,
}
})
My Codes Results:
Hi i'm new in REACT NATIVE, i have a in my react native app, with style of a card like the code below. first i want to split it into two horizontally parts with the ratio of( 3 for upper part and 2 for lower part). And second i want to write on each part.
I
import React from "react";
import {
Button,
StyleSheet,
Text,
View,
TouchableHighlight,
TouchableOpacity,
} from "react-native";
export default function App() {
return(
<View style={styles.card}>
<View style={styles.results}>
<Text style={styles.texty}>numbers</Text>
</View>
<View style={styles.calculations}>
<Text>numbers</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
card: {
flex: 1,
width: "80%",
height: 100,
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 5,
backgroundColor: "white",
padding: 100,
borderRadius: 15,
marginTop: 80,
margin: 42,
justifyContent: "center",
},
texty: {
fontSize: 30,
},
calculations: {
fontSize: 34,
},
results: {
flex: 6,
paddingTop: 25,
justifyContent: "center",
alignItems: "flex-end",
borderBottomWidth: 0.3,
borderBottomColor: "grey",
});
brought my code down there
Please use flex property to achieve this like:
card: { flex: 1 }
results: { flex: .6, flexWrap:'wrap'}
calculations: {flex:.4, flexWrap:'wrap'}
P.S:
You can add other styles as you like but don't use height property.
I would like to add one of these slider toggle buttons to my react native app. Are there any easy ways to do this without starting from scratch?
Example video
The idea is make the background can be animated.
See the sample i've created.
Happy coding!
This is a basic example of how you can achieve this using Animated API.
import React from 'react';
import {
Animated,
Easing,
StyleSheet,
Pressable,
View,
Text,
} from 'react-native';
const App = () => {
const animatedValue = React.useRef(new Animated.Value(0)).current;
const startAnimation = (toValue) => {
Animated.timing(animatedValue, {
toValue,
duration: 400,
easing: Easing.linear,
useNativeDriver: false,
}).start();
};
const left = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: ['2%', '50%'],
extrapolate: 'clamp',
});
const scale = animatedValue.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [1, 0.9, 1],
extrapolate: 'clamp',
});
return (
<View style={styles.container}>
<View style={styles.sliderContainer}>
<Animated.View style={[styles.slider, { left }]} />
<Pressable
style={styles.clickableArea}
onPress={startAnimation.bind(null, 0)}>
<Animated.Text
style={[styles.sliderText, { transform: [{ scale }] }]}>
Active
</Animated.Text>
</Pressable>
<Pressable
style={styles.clickableArea}
onPress={startAnimation.bind(null, 1)}>
<Animated.Text
style={[styles.sliderText, { transform: [{ scale }] }]}>
History
</Animated.Text>
</Pressable>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
sliderContainer: {
width: '90%',
height: 50,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#e0e0e0',
},
clickableArea: {
width: '50%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
},
sliderText: {
fontSize: 17,
fontWeight: '500',
},
slider: {
position: 'absolute',
width: '48%',
height: '90%',
borderRadius: 10,
backgroundColor: '#f4f4f4',
},
});
export default App;
Here you can check out the demo of how it works.
use native base tabs and then customize them .
this link will help you
https://docs.nativebase.io/Components.html#tabs-def-headref
Works fine on iOS:
Gets covered outside of box on Android:
I read somewhere that zIndex only affects sibling components, though this works on iOS.
How should I go about fixing it on Android?
https://snack.expo.io/#riwu/animated-zindex
import React from 'react';
import { View, Animated, PanResponder } from 'react-native';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
pos: new Animated.ValueXY(),
};
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event([
null,
{
dx: this.state.pos.x,
dy: this.state.pos.y,
},
]),
});
}
render() {
return (
<View
style={{
marginTop: 20,
borderWidth: 1,
padding: 5,
width: 50,
height: 50,
}}
>
<Animated.Image
{...this.panResponder.panHandlers}
style={[this.state.pos.getLayout(), { flex: 1, zIndex: 1 }]}
source={{ uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png' }}
/>
</View>
);
}
}
export default App;
For the zIndex to take effect, you need to make the position of the elements as absolute, to overlap each other.
Therefore the resulting code will look like this
<View >
<View
style={{
marginTop: 20,
borderWidth: 1,
width: 50,
height: 50,
position: 'absolute',
zIndex: 1
}}
>
</View>
<Animated.Image
{...this.panResponder.panHandlers}
style={[this.state.pos.getLayout(), { marginTop: 25, marginLeft: 5, height: 40, width: 40, position: 'absolute', zIndex: 2}]} //...Adding appropriate margin, height and width as per parent element
source={{ uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png' }}
/>
</View>
Here's the sample snack demo
I am following this tutorial online: https://medium.com/appandflow/react-native-scrollview-animated-header-10a18cb9469e
I want to take his example and have a cancel button int he top left-hand corner while the title is still properly displayed at the top center just like in his example. However, When I add the cancel button, the title always appears right next to it on the left hand side. what am I doing wrong with my flexbox styling?
App.js:
import React, { Component } from 'react';
import {
Animated,
Platform,
StatusBar,
StyleSheet,
Text,
View,
Image,
} from 'react-native';
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import images from '../../config/images';
const HEADER_MAX_HEIGHT = 300;
const HEADER_MIN_HEIGHT = Platform.OS === 'ios' ? 60 : 73;
const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
scrollY: new Animated.Value(0),
};
}
_renderScrollViewContent() {
const data = Array.from({ length: 30 });
return (
<View style={styles.scrollViewContent}>
{data.map((_, i) => (
<View key={i} style={styles.row}>
<Text>{i}</Text>
</View>
))}
</View>
);
}
render() {
const headerTranslate = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [0, -HEADER_SCROLL_DISTANCE],
extrapolate: 'clamp',
});
const imageOpacity = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [1, 1, 0],
extrapolate: 'clamp',
});
const imageTranslate = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [0, 100],
extrapolate: 'clamp',
});
const titleScale = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [1, 1, 0.8],
extrapolate: 'clamp',
});
const titleTranslate = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0, -8],
extrapolate: 'clamp',
});
return (
<View style={styles.fill}>
<StatusBar
translucent
barStyle="light-content"
backgroundColor="rgba(0, 0, 0, 0.251)"
/>
<Animated.ScrollView
style={styles.fill}
scrollEventThrottle={1}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
{ useNativeDriver: true },
)}
>
{this._renderScrollViewContent()}
</Animated.ScrollView>
<Animated.View
style={[
styles.header,
{ transform: [{ translateY: headerTranslate }] },
]}
>
</Animated.View>
<Animated.View
style={[
styles.bar,
{
transform: [
{ scale: titleScale },
{ translateY: titleTranslate },
],
},
]}
>
<Image
//style={styles.icon}
source={images.icons.cancel}/> // cancel button/icon I want to add
<Text style={styles.title}>Title</Text>
</Animated.View>
</View>
);
}
}
const styles = StyleSheet.create({
fill: {
flex: 1,
},
content: {
flex: 1,
},
header: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
backgroundColor: '#2c6da4',
overflow: 'hidden',
height: HEADER_MAX_HEIGHT,
},
backgroundImage: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
width: null,
height: HEADER_MAX_HEIGHT,
resizeMode: 'cover',
},
bar: {
backgroundColor: 'transparent',
marginTop: Platform.OS === 'ios' ? 28 : 38,
height: 32,
position: 'absolute',
top: 0,
left: 0,
right: 0,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
flex: 1
},
title: {
color: 'white',
fontSize: 18,
flex: 1 // added this but does not display in the center.
},
scrollViewContent: {
marginTop: HEADER_MAX_HEIGHT,
},
row: {
height: 40,
margin: 16,
backgroundColor: '#D3D3D3',
alignItems: 'center',
justifyContent: 'center',
},
icon: {
//alignItems: 'flex-start',
//flex: 1,
//justifyContent: 'flex-start'
},
});
This is what I am currently getting:
/config/images.js:
const images = {
icons: {
cancel: require('../images/cancel.png')
}
};
export default images;