React Native Scroll View Question (keep track of full page scroll loaction) - javascript

I have a scroll view that contains an image that covers the entire screen. There are two buttons at the bottom of the screen, these will allow you to download or set the image as a wallpaper. The problem I'm having is I don't know which image is being looked at in the horizontal scroll view when the button is clicked.
I have knowledge of the screen size and was assuming if I could get the content offset or something like that from the currently viewed image in the view divided by the screen size could let me know what image in the array I'm looking at to perform the rest of the functionality.
unfortunately, I'm unaware of how this could be done the code is below to give a bit of context.
<ScrollView
horizontal
decelerationRate={0}
snapToInterval={width}
snapToAlignment={"center"}
style={{ height: height }}
>
{
availibleBackgrounds.map(element => (
<Image
style={{ width: width, height: height, justifyContent: 'flex-end', alignItems: 'center' }}
source={{
uri: element
}}
/>
))
}
</ScrollView>
Thanks in advance,
Chris.

You need to get the offset of the content and you can do it with adding the following prop the the ScrollView:
onMomentumScrollEnd={event => setSelectedIndex(event.nativeEvent.contentOffset.x/width)}
setSelectedIndex is a function you should create.

To add a little more closure to this question here's what I've done
calculateCurrentIndex(position) {
this.setState({
selectedIndex: {
current: Math.ceil((position / width).toFixed(2)),
}
});
}
----------------------------------------
<ScrollView
horizontal
decelerationRate={0}
snapToInterval={width}
snapToAlignment={"center"}
style={{ height: height }}
onMomentumScrollEnd={event => this.calculateCurrentIndex(event.nativeEvent.contentOffset.x)}
showsHorizontalScrollIndicator={false}
>
{
availibleBackgrounds.map((element, index) => (
<Image
key={index}
style={{ width: width, height: height, justifyContent: 'flex-end', alignItems: 'center' }}
source={{
uri: element
}}
/>
))
}
</ScrollView>

Related

How to align card-images next to each other in react native

I just started with react native, I wanted to align card images next to each other (react-native-elements) but it does not work for some reason. What I want to achieve is two rows in on phones and 3 rows on tablets. But for some reason my code does not work. First the cards are aligned connected to each other no space between them and on my phone (Iphone 12) it is aligned as a column. Even though I have set flex-direction to row. could someone look at my code and tell me what is wrong?
card-image element
<View style={styles.secondPartOfDisplay}>
{categories.map((c,i) => {
return (
<View key={i} style={{width: 200, height: 150, flexDirection: 'row'}}>
<Card.Image >
<Image
style={{width:200,height:150}}
resizeMode="cover"
source={c.imageSource}
/>
</Card.Image>
</View>
)
})}
</View>
styles:
secondPartOfDisplay: {
paddingTop: 30,
display:'flex',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: "space-between"
},
And here is the image on how it looks on phone:
This is how it looks on ipad:
If there iis no extra margin or padding that's messing with your container grid, then probably your images are not responsive according to the screen size. You would probably need to set your image height: "100%" and width: "auto"
Hope this resolves your issue.

ScrollView: Problems with height and scrolling

I have a <ScrollView />. In the documentation it says
Keep in mind that ScrollViews must have a bounded height in order to work, since they contain unbounded-height children into a bounded container (via a scroll interaction). In order to bound the height of a ScrollView, either set the height of the view directly (discouraged) or make sure all parent views have bounded height.
This is my markup:
<View
style={{
paddingLeft: 15,
paddingRight: 15,
width: '100%',
height: Dimensions.get('window').height,
alignItems: 'center'
}}>
<Foo /> // Custom Component with specific height
<ScrollView
style={{width: '100%'}}
...
{foo.map((obj, index) => {
return <View
key={index}
style={{
display: 'flex',
width: '100%',
paddingTop: 2,
paddingBottom: 2,
}}
...
</View>
})
}
</ScrollView >
</View>
In my markup, I have set the height of the parent <View /> with Dimensions.get.... But the <ScrollView /> is not scrolling all the way to the bottom.
Why is the <ScrollView /> not behaving as expected? I want to be able to scroll all the way down and see all the elements.
make shure ScrollView has flex: 1 set in style props.
Forgetting to transfer {flex: 1} down the view stack can lead to errors here, which the element inspector makes quick to debug.

React Native - How to make portion of TouchableOpacity not pressable

I have a Card component that displays a listing on the app's dashboard page. The whole card is wrapped in a TouchableOpacity. I want the entire card to be Pressable, which links to the listings page.
However, I want the bottom right corner of it to not be pressable, since it contains a View that has 2 icons on it (a Like button and a Message button). Each of these icons has their own onPress() that needs to happen.
Right now, if you try to click on the bottom right icons, it just triggers the whole TouchableOpacity
Here is the return statement for Card:
return (
<Container>
<Cover style={{ backgroundColor: "red" }}>
<Image
source={{
width: 80,
height: 90,
url: "https://picsum.photos/200/300",
}}
/>
</Cover>
<Content>
<Title>{props.name}</Title>
<PriceCaption>{"$" + props.price}</PriceCaption>
<View
style={{
position: "absolute",
height: 35,
width: 100,
top: 45,
right: 0,
flexDirection: "row",
alignItems: "Flex-end",
}}
>
<TouchableOpacity
style={{
...styles.ButtonBackground,
backgroundColor: null,
left: 70,
}}
onPress={() => {
launchChat();
}}
title={"message"}
>
<AntDesign name="mail" size={26} color={colours.purple} />
</TouchableOpacity>
<TouchableOpacity
style={{
...styles.ButtonBackground,
backgroundColor: null,
marginLeft: 0,
left: 10,
}}
onPress={() => {
launchChat();
}}
title={"message"}
>
<AntDesign name="heart" size={26} color={colours.purple} />
</TouchableOpacity>
</View>
</Content>
</Container>);
Is there a property, or way I can exclude a nested View from a TouchableOpacity?
Note: If you click on the Icons, they still trigger their respective onPress(), however, the entire Card still fades out, and the animation is the same as if you clicked elsewhere on the card (so user gets poor feedback on where they clicked).
I have an understanding problem in your question, but I believe that wrapping with TouchableWithoutFeedback might be a solution or pointerEvents={"none"} property. If you do a little research on the keyword TouchableWithoutFeedback component from react-native, I think you will get the result you want
I frequently place some TouchableOpacity in other TouchableOpacities. When you press on inner TO, the inner will be pressed not the parent. So you shouldn't think about making some area of parent unpressable.
I just test my sample code to be sure. As I said earlier, it should work. I have no idea what causes this problem in your case.

How can i render Text inside image background in react native?

I want to render a text component inside ImageBackground component.
What i tried is
<ImageBackground
source={{uri: smartPaperData.backgroundImage}}
resizeMode="contain"
resizeMethod="scale"
style={{
height: '100%',
width: undefined,
backgroundColor: 'yellow',
}}>
<Text>Hello</Text>
</ImageBackground>
By using the above code this is what im getting. (you can see hello at the left top)
I need Hello text to come in top left of the image, but text is coming somewhere else.
Can anyone help me in sorting this out
width is totally depend on the raw image size . you need to create container with fix width like
<View style={{width: '80%'}}>
<ImageBackground
source={{uri: smartPaperData.backgroundImage}}
resizeMode="contain"
resizeMethod="scale"
style={{
height: '100%',
width: '100%',
backgroundColor: 'yellow',
}}>
<Text>Hello</Text>
</ImageBackground>
</View>

How can I position two buttons on top of the background side by side and at the bottom of the screen in React Native?

I have a container with a position of relative and an inner </View> element with a position of absolute so the buttons sit on top of the video screen in the background.
When I give the latter its property of absolute, it no longer stays at the bottom of the screen, but I need to give it this so it stays 'on top' of the image behind it.
Here are screenshots of before and after the inner element position on absolute:
Here's my code including the absolute property:
if (props.stream) {
return (
<>
<TouchableWithoutFeedback onPress={handleScreenPress}>
<View style={styles.videoViewWrapper}>
<RTCView style={styles.android} streamURL={props.stream.toURL()} />
<CountDown time={time} />
{/* {showButtons && */}
<View style={{
// position: 'absolute',
}}>
<Button
icon="phone"
mode="contained"
style={{ width: 200, margin: 10 }}
onPress={handleEndCall}
>
End Call
</Button>
<Button
icon="phone"
mode="contained"
style={{ width: 200, margin: 10 }}
onPress={handleSpeakerSwitch}
>
Speaker
</Button>
</View>
{/* } */}
</View>
</TouchableWithoutFeedback>
</>
);
}
return (<> <Loader title="Connecting Your Call.." /> </>)
}
const styles = StyleSheet.create({
videoViewWrapper: {
flex: 1,
overflow: 'hidden'
},
android: {
flex: 1,
position: 'relative',
backgroundColor: 'black'
}
})
export default VideoCall;
I am seeking some tips as to how I could align the two buttons side by side at the bottom and on top of the image behind it, as I'm struggling.
If you want to achieve something like this, then see the code :
Check code :
export default class App extends React.Component {
render() {
return (
<View style={{flex:1}}>
<View style={{flex:1, flexDirection:'row', alignItems:'flex-end',}}>
<TouchableOpacity
style={{width:'40%' , backgroundColor:'blue' ,marginHorizontal:10}}
>
<Text style={{color:'white',alignSelf:'center', padding:5}}>End Call</Text>
</TouchableOpacity>
<TouchableOpacity
style={{width:'40%', backgroundColor:'blue',marginHorizontal:10}}
>
<Text style={{color:'white',alignSelf:'center', padding:5}}>Pick Call</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
check the link : expo snack
Hope it helps .feel free for doubts
Either you can give them separate positioning, top and left for the first, and top and right for the second button, or put them in a view and set flexDirection of the view to row so they could stay side by side. I have a card object and two buttons on top of it, and it works that way.

Categories

Resources