I am currently working on a react native component. I want to assign the height of an image to a specific value that is calulated dynamically with the screen width. I am storing the value in a variable aspectHeight. I want to assign that value to the height in the stylesheet that I am currently calling. It is giving me the issue that the variable can not be found and I do not know how to solve this issue. I checked and I couldnt find any type of solution for this issue.
Here is my component;
import React from 'react'
import { Dimensions } from 'react-native'
import { View, Text, StyleSheet, Image } from 'react-native'
export default function PropertyTile() {
let deviceWidth = Dimensions.get('window').width - 16
var aspectHeight = (deviceWidth / 1.78) + 1
return (
<View style={styles.container}>
<View style={styles.imageContainer}>
<Image style={styles.mainImage} source={require('../../assets/luxury-home-1.jpeg')}/>
</View>
<View className='content-container'>
<Text>asdfas Tile</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
height: '100%',
padding: 8
},
imageContainer: {
height: aspectHeight,
width: '100%',
backgroundColor: 'skyblue'
},
mainImage: {
width: '100%',
height: '100%'
}
})
Replace it with this;
import React from 'react'
import { View, Text, StyleSheet, Image, Dimensions } from 'react-native'
export default function PropertyTile() {
let deviceWidth = Dimensions.get('window').width - 16
var aspectHeight = (deviceWidth / 1.78) + 1
return (
<View style={styles.container}>
<View style={[styles.imageContainer,{height: aspectHeight}]}>
<Image style={styles.mainImage} source={require('../../assets/luxury-home-1.jpeg')}/>
</View>
<View className='content-container'>
<Text>asdfas Tile</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
height: '100%',
padding: 8
},
imageContainer: {
width: '100%',
backgroundColor: 'skyblue'
},
mainImage: {
width: '100%',
height: '100%'
}
})
Nice day, good sir
Related
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;
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 }
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
}}>
i'm building a simple bughouse (4-person chess) game as my first React Native app, and i'm a little confused about a styling issue. the issue occurs when rendering an ImageBackground, which contains a View, which contains a grid of Views (the chess board). when using the code laid out following this question, the View is not contained within the screen (see screenshot below). how do i set the style of a View contained within an ImageBackground so that the View stays contained within the ImageBackground?
screenshot
i've tried about everything i can think of but nothing has helped. i suspect the issue has something to do with the dimensions of the ImageBackground not being set properly and actually extending past the edge of the screen. when i comment out the line that says width: Dimensions.get('screen').width, in styles.board in BoardView.js, the image for the ImageBackground also fills up the same too-big space.
here is views/Game.js:
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import {
SafeAreaView,
View,
StyleSheet,
Platform,
StatusBar,
} from 'react-native';
import { BoardView } from '../components/BoardView';
import { Navbar } from '../components/Navbar';
export function Game () {
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0,
},
bottomBar: {
flex: 2,
width: '100%',
backgroundColor: 'black',
justifyContent: 'center',
},
});
return (
<SafeAreaView style={styles.mainContainer}>
<Navbar />
<BoardView />
<View style={styles.bottomBar}>
</View>
</SafeAreaView>
);
}
here is components/BoardView.js:
import React, { Component } from 'react';
import {
StyleSheet,
ImageBackground,
Dimensions
} from 'react-native';
import { Pieces } from "./Pieces";
export function BoardView () {
const styles = StyleSheet.create({
board: {
flex: 10,
width: Dimensions.get('screen').width,
},
});
return (
<ImageBackground
resizeMode='contain'
style={styles.board}
source={require('../assets/board.png')}
>
<Pieces />
</ImageBackground>
);
}
here is components/Pieces.js:
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import {
View,
StyleSheet,
Text,
} from 'react-native';
export function Pieces () {
const styles = StyleSheet.create({
grid: {
borderColor: 'green',
borderWidth: 5,
alignSelf: 'center',
aspectRatio: 1,
overflow: 'visible',
width: '100%',
height: '100%',
},
gridRow: {
flexDirection: 'row',
flex: 1,
},
gridTile: {
borderWidth: 1,
borderColor: 'green',
flex: 1,
height: '100%',
},
test: {
color: 'green',
},
});
let pieces = [
[['bRook'],['bKnight'],['bBishop'],['bQueen'],['bKing'],['bBishop'],['bKnight'],['bRook']],
[['bPawn'],['bPawn'],['bPawn'],['bPawn'],['bPawn'],['bPawn'],['bPawn'],['bPawn']],
[[''],[''],[''],[''],[''],[''],[''],['']],
[[''],[''],[''],[''],[''],[''],[''],['']],
[[''],[''],[''],[''],[''],[''],[''],['']],
[[''],[''],[''],[''],[''],[''],[''],['']],
[['wPawn'],['wPawn'],['wPawn'],['wPawn'],['wPawn'],['wPawn'],['wPawn'],['wPawn']],
[['wRook'],['wKnight'],['wBishop'],['wQueen'],['wKing'],['wBishop'],['wKnight'],['wRook']],
];
return (
<View style={styles.grid}>
{pieces.map((row, index) =>(
<View style={styles.gridRow} key={index}>
{row.map((tile, index) => (
<View style={styles.gridTile} key={index}>
<Text style={styles.test}>
{tile}
</Text>
</View>
))}
</View>
))}
</View>
);
}
how do i set the style so that the View stays contained within the ImageBackground? thank you very much for your help!
I am trying to truncate a text in my reactnative app. I've decided to use the "ellipsizeMode" attribute, but I can't get it to work.
I wrote a demo of the problem :
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
export class EllipsizeModeTest extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>{'first part | '}</Text>
<Text style={styles.text} numberOfLines={1} ellipsizeMode={'tail'}>
{'a text too long to be displayed on the screen'}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
},
text: {
fontSize: 20,
}
});
Now the text does not get truncated, any idea why ?
I had the same problem, it's enough to have the size of the element bound to a value. So if you define width, or add a flex value will work.
<View style={{width: 200}}><Text ellipsizeMode='tail' numberOfLines={1}></View>
You need to set a width on your Text element so it knows when to ... it
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
},
text: {
fontSize: 20,
width: 100
}
});
Try assigning a string to ellipsizeMode (remove the curly brackets):
<Text style={styles.text} numberOfLines={1} ellipsizeMode='tail'>
Try setting a width style property to the component
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
export class EllipsizeModeTest extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>{'first part | '}</Text>
<Text style={styles.text} numberOfLines={1} ellipsizeMode={'tail'}>
{'a text too long to be displayed on the screen'}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
},
text: {
fontSize: 20,
width: 100
}
});