Scrollable Background Image in React Native - javascript

I'm trying to add an image in the background of a screen which is very long and I want the image to be scrollable. Please give suggestions/code snippets for me to achieve this.

Just put the image inside a ScrollView like this
export default function App() {
return (
<>
<ScrollView >
<ImageBackground
style={{
height: 1000,
width: '100%',
}}
source={{
uri: 'https://i.stack.imgur.com/zkNF4.jpg',
}}
/>
</ScrollView>
</>
);
}
Let me know if it worked

Related

ScrollView not working in react-native app, content disappears when attempting to add flex and flexGrow

for some reason a ScrollView in one of my components isn't working despite working in every other component I've implemented it in. Attempting to implement solutions to similar problems seems to just make the content I want displayed disappear.
I'm expecting to have a scrollable list of sample restaurant dishes. I created some dummy data to pass in for now but noticed it didn't scroll after reaching the end of the phone screen.
const testFoods = [
{
title: "test",
description: "Lorem Ipsum",
price: "$7.77",
image: "dummyLink",
},
// Same as above but 4 more times, didn't want to clog up the description
];
export default function MenuItems() {
return (
<ScrollView showsVerticalScrollIndicator={false}>
{testFoods.map((food, index) => (
<View key={index}>
<View style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</View>
</View>
))}
</ScrollView>
);
}
const FoodDetails = (props) => (
<View style={{ width: 240, justifyContent: "space-evenly" }}>
<Text style={styles.titleStyle}>{props.food.title}</Text>
<Text>{props.food.description}</Text>
<Text>{props.food.price}</Text>
</View>
);
const FoodImage = (props) => (
<View>
<Image
source={{ uri: props.food.image }}
style={{
width: 100,
height: 100,
borderRadius: 8,
}}
/>
</View>
);
const styles = StyleSheet.create({
menuItemStyle: {
flexDirection: "row",
justifyContent: "space-between",
margin: 20,
},
titleStyle: {
fontSize: 19,
fontWeight: "600",
},
});
The result is like so
Result with code above
The Header component with the sample restaurant image is a separate component by the way.
I have more data that can't be seen as for whatever reason the screen refuses to scroll. I'm using my actual phone for the tests but the result is the same when I use an emulator, scrolling doesn't work. After looking online I thought I would try adding a parent View with flex: 1 and a flexGrow: 1 to contentContainerStyle inside the ScrollView like so.
export default function MenuItems() {
return (
<View style={{ flex: 1 }}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ flexGrow: 1 }}
>
{testFoods.map((food, index) => (
<View key={index} style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</View>
))}
</ScrollView>
</View>
);
}
But that only resulted in the content disappearing. Reloading the app didn't change anything either Result after trying above code
Attempting to use a FlatList had the same result. I've also read that having percentage based styling values on height for any of the children components can make the scrolling stop working but all my components don't utilize such. Oddly enough when I change the styling on the outer view to height: 400, I'm able to get the scrolling to work but this is very sloppy and will likely only work on phone screens similar to mine. I know the ScrollView component is working fine, as when I add "horizontal" to it the scrolling works just fine and I'm able to scroll to the last item in the dataset. Obviously all the content is horizontal now though. After adding horizontal too ScrollView, scrolling works fine horizontally
Any ideas? Could it be some part of my styling I'm not noticing? I'm unable to test this on IOS so I'm not sure if it's an Android specific problem, would be strange though as scrolling worked fine in my other components.
Here's also the Header component code just in case it could be anything in there, although It shouldn't be.
const testImage =
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Restaurant_N%C3%A4sinneula.jpg/800px-Restaurant_N%C3%A4sinneula.jpg";
const testTitle = "Sample Restaurant";
const testDescription = "Thai · Comfort · $$ · 🎫 · 4 ⭐ (217+)";
export default function About() {
return (
<View>
<RestaurantImage image={testImage} />
<RestaurantTitle title={testTitle} />
<RestaurantDescription description={testDescription} />
</View>
);
}
const RestaurantImage = (props) => (
<Image source={{ uri: props.image }} style={{ width: "100%", height: 180 }} />
);
const RestaurantTitle = (props) => (
<Text
style={{
fontSize: 29,
fontWeight: "600",
marginTop: 10,
marginHorizontal: 15,
}}
>
{props.title}
</Text>
);
const RestaurantDescription = (props) => (
<Text
style={{
marginTop: 10,
marginHorizontal: 15,
fontWeight: "400",
fontSize: 15.5,
}}
>
{props.description}
</Text>
);
Wrap your card with TouchableOpacity.
<TouchableOpacity activeOpacity={0} key={index} style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</TouchableOpacity>
I hope this thing will work.

How to use variable as image source

I'm creating this Instagram Clone, I have the image local url and I want to show it to the user before he posts it.
I tried to crate a state var, tried to require but nothing works
<Image source={this.state.img_url} />
This is what I need, thanks for helping me!
Here is the solution I found
render(){
//Getting image from Camera Screen
var imgSource = this.state.img_url;
return(
<View>
<Image
source={{ uri: imgSource }}
style={{width: 400, height: 400}}
/>
</View>
);
}
For showing image in react-native, you need to provide an object which contains uri property.
Below code will set a responsive image
<View>
<Image source={{ uri: 'image-path' }} style={{ height: 300, flex: 1, width: null }}>
</View>

How to put a sticky Touchable within an horizontal ScrollView in React Native?

I am trying to make a simple application/game to learn and practice React Native. Currently, I am trying to create a sticky TouchableNativeFeedback that moves with the screen as I am using the ScrollView.
The idea is that left half of the screen would move the character to the left and the right half of the screen would move it to the right. I want these controls to be fixed in the display and not move.
This is how it starts
This is after moving the scrollView a bit
I've initially tried to change value of style.left as I scrolled but that doesn't seem to be a good/stable solution.
Here is the current code:
render() {
return (
<ScrollView
//onScroll={this._onScroll}
ref={(scrollView) => { this.scrollView = scrollView; }}
style={styles.container}
horizontal= {true}
snapToAlignment={"center"}
>
<View style={styles.wrapperView}>
<ImageBackground
style={styles.container}
source={require('../images/second.png')}
>
<TouchableNativeFeedback onPressIn={this._onPressButton} onPressOut={this._onPressButton}>
<View style={
{
width: width/2,
height: '100%',
position: 'absolute',
left: this.state.touchableLeft,
backgroundColor: 'red',
}
}>
</View>
</TouchableNativeFeedback>
... (code about the character)
</ImageBackground>
</View>
</ScrollView>
);
}
and the styles code
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
},
wrapperView:{
width: width*3 + 300,
},
});
and just to have it as a reference, this is what I originally tried:
_onScroll = (event) => {
this.setState( {
touchableLeft: this.state.touchableLeft + event.nativeEvent.contentOffset.x
} )
}
I've looked at the following questions and articles but I couldn't really get to a solution that would help me. Usually people use flex to make their headers sticky above a ScrollView and that is incredibly handy but in this situation I am unsure about how to continue. Articles/Questions:
How to Get ListView Section Header to Stick
http://docs.nativebase.io/docs/examples/StickyHeaderExample.html
Sticky Component inside scrollview
What solved my problem was to take the TouchableNativeFeedback outside of the class. The class in the question was called Background and it was rendered in the class called App.
<View style={styles.container}>
<Background />
<TouchableNativeFeedback onPressIn={this._onPressButton} onPressOut={this._onPressButton}>
<View style={
{
width: '50%',
height: '100%',
position: 'absolute',
left:0,
//left: this.state.touchableLeft,
//backgroundColor: 'red',
}
}>
</View>
</TouchableNativeFeedback>
</View>
As you can see once I moved it to here, it was positioned right where I wanted, even if I move the screeen. What would be good practice, is to take it to another component class and then just call an instance of it.
Thanks to John Ruddell for the help while coming up with the solution

React Native Swiper multiple images

I'm using the react-native-swiper, but I didn't find any solution for my problem in the docs. Currently it's show me one picture at once. But I want one and half, and always slide one by one. Is it possible somehow, because the slides have a strict width.
A design what I would achive:
There is my current code:
class Featured extends Component {
/**
* Render the featured box
*/
renderFeatured() {
return this.props.featured.data.items.map(object => (
<View style={styles.slide} key={object.id}>
<FeaturedBox
id={object.id}
image={Helpers.getPrimaryImage(object.images)}
text={object.name}
/>
</View>
)
);
}
render() {
if (Helpers.isObjectEmpty(this.props.featured)) {
return (
<View />
);
}
return (
<View>
<Swiper
style={styles.wrapper}
height={150}
horizontal={false}
showsPagination={false}
>
{this.renderFeatured()}
</Swiper>
</View>
);
}
}
const styles = StyleSheet.create({
wrapper: {
},
slide: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Basically the FeaturedBox is just an image.
I found the solution, and change the Swiper to Carousel.
I had the same problem with you.
I tried many times, eventually solved this problem and I created npm package for these use cases.
First of all, You can solve this error by adding specific width in the images via your device.
If your use cases is adding multiple images, then you can solve that easily by using method below.
Hope react-native-image-swiper helps you.
usage
import {Dimensions} from 'react-native';
import ImagesSwiper from "react-native-image-swiper";
const { width, height } = Dimensions.get("window");
<ImagesSwiper width={width} height={height-400} />
I suggest you to use react-native-snap-carousel
follow below link for more details
https://www.npmjs.com/package/react-native-snap-carousel
You can do this via following code;
<Swiper removeClippedSubviews={false}>
<View style={{width: screenWidth - 100}}></View>
<View style={{marginLeft: - 100}}> </View>
</Swiper>

React Native: WebView height isn't being set properly

I'm having a problem with a WebView in my React Native app. When no height for the WebView is specified, it defaults to about half the screen height (iPhone 6S). However, when I set a height with the help of Dimensions, it displays fine, but only the original half is interactive – ie. can only scroll using the top half of the screen.
Here are the main parts of my current code:
import React, { Component } from 'react';
import {
...
Dimensions,
...
WebView,
} from 'react-native';
let ScreenHeight = Dimensions.get("window").height;
let ScreenWidth = Dimensions.get("window").width;
class App extends Component {
render() {
return (
<View style={styles.container}>
...
<WebView
source={{uri: 'http://foo.com'}}
style={{height: ScreenHeight, width: ScreenWidth}}
/>
...
</View>
);
}
}
...
const styles = StyleSheet.create({
container: {
backgroundColor: '#bbb',
flex: 1,
},
...
});
AppRegistry.registerComponent('myApp', () => App);
I look forward to any help that can be offered :)
It's possible that an invisible view from your render function is being drawn on the bottom half of the screen.
With out seeing the rest of the render method I couldn't tell, still worth checking.
Thanks for the answers, guys. I've fixed my issue now, and it seems to be such an easy fix. I basically wrapped the WebView in it's own View container. I'm not sure whether it wasn't working because it had sibling elements (ie. NavBar and TabBarIOS – which I left off my previous snippet – sorry!), but the WebView now works great.
Here is my new render function:
render() {
return (
<View style={styles.container}>
<NavBar>
<View>
<WebView
source={{uri: 'http://foo.com'}}
style={{height: ScreenHeight, width: ScreenWidth}}
/>
</View>
<TabBarIOS>
...
</TabBarIOS>
</View>
);
}
Try adding flex style to WebView. Your code will look like this:
<View style={styles.container}>
...
<WebView
source={{uri: 'http://foo.com'}}
style={{flex:1}}
/>
...
</View>

Categories

Resources