How to Handle overflowing elements in React-native? - reactjs

How to use flex in react-native to make any element inside <View></View> to arrange themselves when their length got bigger than their container's ?
Below is my code:
const FilmCasts = ({ artists }) => (
<View style={{ flex: 1, flexDirection: 'row', }}>
{artists.map(artist => (
<Image
key={cast.name}
source={{ uri: artist.img }}
style={{ width: 80, height: 100 }}
/>
))}
</View>
);
This is what I want. I want to make the 5th and others to go below the first row automatically after they hit the screen width limit, like what HTML usually does
But instead, this is what I get when in React Native, the <Image> elements continue to be rendered outside their parent's width

You can use the prop flexWrap:'wrap' for wrapping the elements. flexWrap controls whether children can wrap around after they hit the end of a flex container. More here
const FilmCasts = ({ artists }) => (
<View style={{ flex: 1, flexDirection: 'row',flexWrap:'wrap' }}>
{artists.map(artist => (
<Image
key={cast.name}
source={{ uri: artist.img }}
style={{ width: 80, height: 100 }}
/>
))}
</View>
);

You can simply defined image with dynamically using the Dimension property of react native .
like when you are using
<Image
resizeMode="cover" or try "contain"
key={cast.name}
source={{ uri: artist.img }}
style={{ width: width * 0.5 , height: 100 }} // this will be done currently defining the values .
/>
Here is one blog regarding image handling in react native Click to see the blog
Hope my answer will give an idea to slove your problem

Related

react native : custom component with color parameter

Im doing the exercises to learn react native on codecademy.
I am told "In React, properties are passed as objects on the first parameter to our components. You need to add this parameter in the custom component and use the color property as the background color."
I need to pass color as a parameter to my Box custom component. This is my code:
export const Box = (color) => (
<View color={color} style={{ width: 100, height: 100, backgroundColor: this.props.color }} />
);
It throws me a syntax error.
I also tried :
export const Box = (color) => (
<View style={{ width: 100, height: 100, backgroundColor: color }} />
);
But I am told "View should have a background color set by the color property.". It's the same when I do
export const Box = (color) => (
<View style={{ width: 100, height: 100, backgroundColor: {color} }} />
);
It's very basic but I'm always mistaken when it comes to calling variables in React and properly using them...
If you could help me that would be great!
thanks
Basically, you can get props like this:
export const Box = ( props ) => (
<View color={props.color} style={{ width: 100, height: 100, backgroundColor: props.color }} />);

react native - Image not showing on custom callout in mapview?

I have a map screen with markers, I try to add image to the callout and I use same method of <image source = .. /> as I did in other place that works, but on the map it wont show me the picture.
{
this.state.markers.map(marker => (
<MapView.Marker
key={marker.id}
coordinate={{longitude: marker.longitude, latitude: marker.latitude}}>
<MapView.Callout>
<View>
<View>
{marker.imageUri && <Image source = {{uri: marker.imageUri}}
style = {{ width: '90%', height: 100, justifyContent: 'center', flex: 1, alignContent: 'center', resizeMode: 'stretch'}}
/> }
</View>
<Text>Lat: {marker.latitude}, Lon: {marker.longitude}</Text>
<Text>{marker.email}</Text>
</View>
</MapView.Callout>
</MapView.Marker>
))
}
it gives me a blank view instead of the image.
Have I done any mistake?
Use Image inside Text component,It is strange but it works :)
<Text> <Image style={{ height: 100, width:100 }} source={{ ... }} resizeMode="cover" /> </Text>
https://docs.expo.io/versions/latest/sdk/webview/
import { WebView } from 'react-native-webview';
If const isAndroid = Platform.OS === 'android'; is true render a WebView... if not render a Image.
I fixed it by using a webView for android: const Img = isAndroid ? WebView: Image; return <Img source={{uri: someUri}} />

How do I play video in react-native only when user sees the full video component?

I am using react-native-video-player to play video in my app. I have a screen that renders sub-components where, in each one of them I have a video player embedded. My question is, how do I only make a video play when the user sees the entirety of the component where the video is embedded? Otherwise a person would hear 10 videos playing simultaneously when entering the screen.
<FlatList
data={this.state.data}
style={{ marginTop: 10 }}
renderItem={({ item }) => (
<DiscoveryPanel
{...item}
componentId={this.props.componentId}
connectionType={this.state.connectionType}
followAction={() => this.followAction(item)}
/>
)}
keyExtractor={item => item.eid}
/>;
const DiscoveryPanel = ({ relevant }) => {
return (
<View style={styles.boxShadow}>
<View style={styles.topContainer}>
<VideoPlayer
thumbnail={{ uri: logo }}
video={{
uri: stream_urls["480p30"]
? stream_urls["480p30"]
: stream_urls["chunked"]
}}
muted={false}
pauseOnPress={true}
autoplay={connectionType == "wifi"}
/>
<Image
style={{ position: "absolute", height: 60, width: 60 }}
source={require("../../../assets/images/record_gif.gif")}
/>
</View>
</View>
);
};
I think there is a window property which tells you the current height. Just use this number in the scroll event

Images load at different rates: uri vs require?

I have two images that appear on the screen at different rates despite the same markup. The only difference I can see is that one image using a uri as a source while the other uses required as it's loaded from an assets directory.
This issue appears in the simulator and on an iPhone.
Code:
state = { opacity: new Animated.Value(0) };
componentDidMount() {
Animated.timing(this.state.opacity, {
toValue: 1,
duration: 1000
}).start();
}
render() {
return(
<View style={{ flex: 1, backgroundColor: 'white' }} >
<View style={{flex: 1}} >
<Animated.Image
style={{ flex:1, height: undefined, width: undefined, opacity: this.state.opacity }}
resizeMode="contain"
source={{uri: this.props.screenProps }}
/>
</View>
<View>
<Animated.Image
source={ require('../assets/images/footer.png') }
style={{height: 170, width: SCREEN_WIDTH, opacity: this.state.opacity}}
/>
</View>
</View>
);
}
}
I would like the calendar quote image and the footer image to load together.
Unfortunately when you mix external images with local images, you're going to have this problem where your local one will (hopefully) load first.
I would start off setting a state variable to handle the logic for showing your local image.
state = {
opacity: new Animated.Value(0),
isVisible: false
}
Create a function that will modify your recently added state variable
setVisibility = () => {
this.setState({
isVisible: true
})
}
(No real need for using a function here when setting state)
Inside of your render() method, simply add some logic. At first this image will not render.
{this.state.isVisible &&
<View>
<Animated.Image
source={require('../assets/images/footer.png')}
style={{ height: 170, width: SCREEN_WIDTH, opacity: this.state.opacity }}
/>
</View>}
Here's where the real magic happens, Image in React Native comes with an onLoadEnd event.
Invoked when load either succeeds or fails.
You can provide additional checks for success or failure, this is not included within this example. Simply add the onLoadEnd prop to your external image component and pass setVisibility as the event handler.
<Animated.Image
style={{ flex: 1, height: undefined, width: undefined, opacity: this.state.opacity }}
resizeMode="contain"
source={{ uri: this.props.screenProps }}
onLoadEnd={this.setVisibility}
/>
You can seen an example on Expo here.

Place array of images one above the other partially in React Native

I am trying to stack an array of images one above the other as shown in the attachment below. With the below code, I am able to stack them one beside the other, however could not overlap them. Appreciate any help.
{array1.edges.map((u, i) => {
if (i > 5) return null;
return (
<Image
source={{ uri: u.node.profilePhoto.url }}
resizeMode="cover"
key={i}
style={{ height: 20, width: 20, borderRadius: 10 }}
/>
);
}
)}
You can set a negative marginLeft to around -10 to get that effect.
marginLeft: -10
Also followed this example rnplay.org/apps/LvdXgg to get it working.

Resources