How to move label along with slider value in React Native - javascript

I am working on a React Native Project, I want to move the label along with the slider value. I tried many ways but its not working accurately.
Here is my code:
import React, { useState } from 'react'
import { Text, StyleSheet, View, Dimensions } from 'react-native'
import Slider from '#react-native-community/slider';
function LabelSlider() {
const windowWidth = Dimensions.get('window').width;
const [value, setValue] = useState(0)
// const left = value * (windowWidth-60)/85;
const [showValue, setShowValue] = useState(false)
//var percent = (percentToGet / 100) * number;
return (
<View>
{showValue ?
<View >
<Text style={{ width:50, textAlign: 'auto', left: value}}>{value}</Text>
</View> :
<></>}
<Slider
style={{ width: 200, height: 40 }}
maximumValue={300}
minimumValue={0}
step={1}
value={value}
onValueChange={(value) => setValue(value)}
onSlidingStart={() => setShowValue(true)}
onSlidingComplete={() => setShowValue(true)}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
/>
</View>
)
}
export { LabelSlider }
I have also attached two images of the output I was able to get:
Image 1,
Image 2

You can use a shared value and interpolate the left position for the label.
Right now what happens is, that the left value goes from 0 to 300. This makes the label unresponsive. You can do something as shown below.
Also, here's a Snack for the implementation.
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Slider from '#react-native-community/slider';
import Animated, {
useSharedValue,
useAnimatedStyle,
interpolate,
Extrapolate,
} from 'react-native-reanimated';
// Constants
const MAX_SLIDER_VALUE = 300;
const MIN_SLIDER_VALUE = 0;
const SLIDER_WIDTH = 200;
export default function App() {
// State to store progress value of slider
const [value, setValue] = React.useState(0);
// Shared value for storing label position
const progress = useSharedValue(0);
// Whenever `value` changes, update the progress shared value
// This will accordingly update the left position of the label
React.useEffect(() => {
progress.value = value;
}, [value]);
// Animate the left position according to the shared value
// Also Extrapolate it so that it doesn't exceed 100%
const animatedStyle = useAnimatedStyle(() => {
const leftPosition = interpolate(
progress.value,
[MIN_SLIDER_VALUE, MAX_SLIDER_VALUE],
[0, 100],
Extrapolate.CLAMP
);
return {
left: `${leftPosition}%`,
};
});
return (
<View style={styles.container}>
<View style={{ width: SLIDER_WIDTH }}>
<Animated.View style={[styles.labelView, animatedStyle]}>
<Text>{value}</Text>
</Animated.View>
<Slider
style={{ width: SLIDER_WIDTH, height: 40 }}
maximumValue={MAX_SLIDER_VALUE}
minimumValue={MIN_SLIDER_VALUE}
step={1}
value={value}
onValueChange={setValue}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
labelView: {
marginBottom: 20,
},
});

You can use react native element slider for this, I have given the example code below
import React from 'react';
import { View } from 'react-native';
import {Slider} from 'react-native-elements';
const App = () => {
return (
<View
style={{
flex: 1,
justifyContent: "center",
}}>
<Slider
thumbStyle={{height: 15, width: 15, backgroundColor: 'orange'}}
maximumTrackTintColor="grey"
minimumTrackTintColor="orange"
thumbProps={{
children: (
<View
style={{
color: 'green',
marginTop: -22,
width: 100,
}}>
<Text>Value</Text>
</View>
),
}}
/>
</View>
)
}
export default App;

Related

in react-native how to use body-pix

import { Camera, CameraType } from 'expo-camera';
import React, { useRef } from "react";
// import logo from './logo.svg';
import * as tf from "#tensorflow/tfjs";
import * as bodyPix from "#tensorflow-models/body-pix";
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
//AFTER IMPORT
export default function App() {
const [type, setType] = useState(CameraType.back);
const [permission, requestPermission] = Camera.useCameraPermissions();
const canvasRef = useRef(null);
//next part
const runBodysegment = async () => {
const net = await bodyPix.load();
console.log("BodyPix model loaded.");
// Loop and detect hands
setInterval(() => {
detect(net);
}, 100)
};
//next part
const detect = async (net) => {
const person = await net.segmentPersonParts(video);
console.log(person);
const coloredPartImage = bodyPix.toColoredPartMask(person);
bodyPix.drawMask(
canvasRef.current,
video,
coloredPartImage,
0.7,
0,
false
);
runBodysegment();
if (!permission) {
// Camera permissions are still loading
return <View />;
}
if (!permission.granted) {
// Camera permissions are not granted yet
return (
<View style={styles.container}>
<Text style={{ textAlign: 'center' }}>We need your permission to show the camera</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
);
}
function toggleCameraType() {
setType(current => (current === CameraType.back ? CameraType.front : CameraType.back));
}
return (
<View style={styles.container}>
<Camera style={styles.camera} type={type}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={toggleCameraType}>
<Text style={styles.text}>Flip Camera</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
//next part
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'transparent',
margin: 64,
},
button: {
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
});
};
I want to use body-pix in my react-native app for android .
can any one help me how to do it .
I want my app to open a camera and in my camera there will be a body body-pix working
in my android app
I want my react-native app to work properly with body-pix
I had try it many time time but I can't do it properly

Interpolate is not a function react native

I follow video at the link https://www.youtube.com/watch?v=YE7c6ch2msY and try do it.
But when I add animated interpolate it show error " interpolate is not a function"
Here is my code
import * as React from 'react';
import { StatusBar, Animated, Text, Image, View, StyleSheet, Dimensions, FlatList } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
const { width, height } = Dimensions.get('screen');
const Indicator = ({ scrollX }) => {
return (
<View style={{ position: 'absolute', bottom: 100, flexDirection: 'row' }}>
{DATA.map((_, i) => {
const inputRange =[(i-1) * width, i* width, (i+1)* width];
const scale = scrollX.interpolate({
inputRange,
outputRange:[0.8,1.4,0.8],
extrapolate:'clamp',
})
return <View key={`indicatot-${i}`}
style={{
height: 10,
width: 10,
borderRadius: 5,
backgroundColor: '#333',
margin: 10
}} />
})}
</View>
)
}
export default function App() {
const scrollX = React.useRef(new Animated.Value(0)).current;
return (
<View style={styles.container}>
<StatusBar hidden />
<Animated.FlatList
...
renderItem={({ item }) => {
return (
...
)
}}>
</Animated.FlatList>
<Indicator scrollX={{ scrollX }} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I can see type of scrollX is any, is not Animted.Value
How I can fix it?
It's just a little typo, you're putting double brackets when passing down the scrollX
<Indicator scrollX={{ scrollX }} />
This means you're passing an object with a property scrollX, just remove one set of brackets scrollX={ scrollX }

How to create custom dropdown list in react-native?

I almost consume 17 hours, but the answers on what I have searched did not satisfy the exact answer to my question,
how to create own custom DropdownList in react native? I already did, the 1st child node which is DropDown (cyan) is work properly, the 2nd child node which is the the List (green) with absolute position but it was not work properly, unless the root parent (red) will also covered the 2nd child node with absolute position, to make it active and clickable, as like what I mention from the picture, Figure 1.0
I set absolute position of the List (green) to make it float from the next child node and the error was persist, the List(parent) was disabled and it cannot click each child items (yellow), unless I set height of the root parent (red) that covered the entire child node but it leads to the next node to adjust the position and do the unexpected layout, like the sample picture Figure 1.1
I DID IT!, the problem is the root parent (red) must not have customized styled property, and I still have one questions, I dont know if it is bug or what, once I did not put any custom property in the style of root parent it works properly, and here is my source code
App.js
import React, { useState } from 'react';
import Separator from './Separator';
import Spinner from './Spinner';
import {
View,
Text,
TouchableOpacity
} from 'react-native';
export default function () {
const [spBusiness, setSPBusiness] = useState({
showList: false,
selectedItem: ''
})
const onShowList = () => {
if (spBusiness.showList) {
setSPBusiness(prev => ({
...prev,
showList: false
}))
}
else {
setSPBusiness(prev => ({
...prev,
showList: true
}))
}
}
const onSelectItem = (item, index) => {
setSPBusiness(prev => ({
showList: false,
selectedItem: item
}));
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff' }}>
<Box text='Rectangle 1' onPress={() => console.log('Rect 1')} />
<Separator vertical={1} />
<Spinner
placeholder='Select Item'
items={['A', 'B', 'C']}
isListShow={spBusiness.showList}
selectedItem={spBusiness.selectedItem}
onShowList={onShowList}
onSelectItem={onSelectItem}
/>
<Separator vertical={1} />
<Box text='Rectangle 2' onPress={() => console.log('Rect 2')} />
<Separator vertical={1} />
</View>
)
}
const Box = props => (
<TouchableOpacity onPress={props.onPress} style={{ zIndex: -1, borderRadius: 7.5, width: 250, height: 45, justifyContent: 'center', alignItems: 'center', backgroundColor: '#242424' }}>
<Text style={{ color: '#fff' }}>{props.text}</Text>
</TouchableOpacity>
)
DropDownList/index.js
import React from 'react';
import styles from './style';
import AIcon from 'react-native-vector-icons/AntDesign';
import {
View,
Text,
Dimensions,
TouchableOpacity,
ScrollView
} from 'react-native';
import Separator from '../Separator';
export default function (props) {
const { items } = props;
const { width, height } = Dimensions.get('window');
const size = size => (size / 100) * width;
const hp = hp => (hp / 100) * height;
const wp = wp => (wp / 100) * width;
return (
<View>
{/* here is the root parent with empty style property*/}
<TouchableOpacity
style={styles.skin}
activeOpacity={0.75}
onPress={props.onShowList}
>
<View style={styles.body}>
<View style={styles.upperBodyPane}>
</View>
<View style={styles.centerBodyPane}>
{props.selectedItem.length === 0 &&
<Text>{props.placeholder}</Text>
}
{props.selectedItem.length !== 0 &&
<Text>{props.selectedItem}</Text>
}
<AIcon name='caretdown' size={size(3.5)} color='#242424' />
</View>
</View>
</TouchableOpacity>
{props.isListShow &&
<ScrollView
style={styles.list}
contentContainerStyle={styles.listContainer}
>
{
items.map((item, index) => (
<View key={index}>
<Item
item={item}
onPress={() => props.onSelectItem(item, index)}
/>
{items.length !== (index + 1) ? <Separator vertical={0.5} /> : null}
</View>
))
}
</ScrollView>
}
</View>
)
}
const Item = props => (
<TouchableOpacity style={styles.item} onPress={props.onPress}>
<Text style={styles.itemText}>{props.item}</Text>
</TouchableOpacity>
)
DropDownList/style.js
import {
Dimensions,
StyleSheet
} from 'react-native';
const { width, height } = Dimensions.get('window');
const size = size => (size / 100) * width;
const hp = hp => (hp / 100) * height;
const wp = wp => (wp / 100) * width;
export default StyleSheet.create({
skin: {
minWidth: wp(70),
height: hp(5.5),
paddingHorizontal: wp(6),
justifyContent: 'center',
backgroundColor: 'cyan',
position: 'relative'
},
body: {
},
centerBodyPane: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
},
item: {
height: hp(5),
paddingHorizontal: wp(5),
justifyContent: 'center',
backgroundColor: 'orange',
},
itemText: {
color: 'white'
},
list: {
top: hp(6.5),
width: wp(70),
maxHeight: hp(15),
backgroundColor: 'green',
position: 'absolute',
},
listContainer: {
padding: size(1.75),
}
})
but the worse case only, I need to set the next child node of DropDownList to zIndex: -1 , but it finally works.

Use percentage/relative values in Styling of <View /> on iOS in react-native

I want to do something like this in react-native
<View
style = { width: '100%', padding: 10, borderRadius: '25%' }>
{...}
</View>
But I get (on iOS)
JSON value '25%' of type NSString cannot be converted to NSNumber
Is there a way to use relative/percentage values as styling input for borderRadius?
You can do something like that, use ref in order to have a reference to that element, then you can measure its width (not in percentage) and you can calculate the border radius.
import React, { useRef, useEffect, useState } from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
const ref = useRef();
const [width, setWidth] = useState(0);
useEffect(() => {
ref.current.measure((x, y, w, h) => {
setWidth(w);
});
}, []);
return (
<View style={styles.container}>
<View
ref={ref}
style={{
width: '80%',
padding: 10,
backgroundColor: 'red',
borderRadius: width / 4, // 25%
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Okay, after a quick researching, i found that borderRadius style expects number as a value, not a String
So if you want to custom the value of borderRadius, you can do sth like this:
<View style={{
width: 300,
height: 300,
backgroundColor: 'red',
padding: 10,
borderRadius: 300/4 // equal 25% of its size
}}>

Styling reusable components in React-Native

I made a reusable component Button.js and I'm importing it on two different screens. The button looks the same, but on the first screen I need it to be position: 'absolute' and on the second one position: 'relative' (the default).
How do I add the position to be absolute on the first screen? I tried to add the styling on FirstPage.js but it does not work. How do I overwrite the style that is defined in Button.js?
Button.js:
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const Button = ({ position, onPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle, {'position': position}}>
<Text style={textStyle}>{children}</Text>
</TouchableOpacity>
);
};
Button.defaultProps = {
position: 'relative',
}
const styles = {
textStyle: {
alignSelf: 'center',
color: '#F44336',
fontSize: 16,
},
buttonStyle: {
zIndex: 2,
width: 100,
backgroundColor: '#FFF',
}
};
export { Button };
You can pass props, something like this (Button.js) (edited according to posted code):
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const Button = ({ position, onPress, children }) => {
const { buttonStyle, textStyle } = styles;
const style = {...buttonStyle, position };
return (
<TouchableOpacity onPress={onPress} style={style}>
<Text style={textStyle}>{children}</Text>
</TouchableOpacity>
);
};
Button.defaultProps = {
position: 'relative',
}
const styles = {
textStyle: {
alignSelf: 'center',
color: '#F44336',
fontSize: 16,
},
buttonStyle: {
zIndex: 2,
width: 100,
backgroundColor: '#FFF',
}
};
export { Button };
Your button of course looks different, this is just an outline of what you could do (basically just using props).
This is REUSABLE Button as touchableOpacity.
export const NormalThemeButton = (props) => {
return (
<TouchableOpacity
style={[{ ...props.style, ...styles.normalThemeBtn }]}
style={[{ alignItems: props.align }, styles.anchor]}
onPress={props.onPress} >
<CustomText text={props.text} l bold style={{
textAlign: 'center',
color: theme['blackColor']
}} />
{props.children}
</TouchableOpacity >
);
};
This is where this RESUABLE Button is been used.
style={{ ...styles.openArrivedButton }}
text={Lng.instance.translate('useWaze')}
onPress={() => { Waze() }}/>
Hope You find it helpful.

Categories