How to put image background in React native? - react-native

I am trying to a background in my react native app and this is my code.
render() {
return (
<View
style={{
alignItems: 'center',
flex:1}}>
<Image
source={darkwallpaper}
style={{
flex: 1,
width: '100%'}}/>
<View
style={{
position: 'absolute',
justifyContent: 'center',
alignItems: 'center'}}>
<ScrollView>
<Text>This is the random Top page</Text>
<Image
source={homemoviespic}
style={{width: '100%'}}/>
<TopMovies />
</ScrollView>
</View>
)
}
Right now, the background shows but the scrollview is not working. I cant scroll and I can see only a few parts of the stuff inside scrollview. Please help.

Found something called ImageBackground that can put image in background and you can just put children in the tag.

<Image> with nested content is no longer supported. Use <ImageBackground> instead.
<ImageBackground style={styles} source={source} resizeMode={resizeMode} >
{children}
</ImageBackground>

Related

justifyContent: 'center' not working React Native

i want to center the image but it seems the justifyContent: 'center' property is not working as i want
I'm learning about flexbox in react-native
Also, I want to ask how can my code run on many different devices without changing the layout. I code on iphone 14 but when I switch to ipad or iphone se, the layout is changed and almost not as expected.
picture
my code
import React from 'react';
import {Dimensions, Image, Text, View} from 'react-native';
import {colors, sizes, spacing} from '../../constants/config';
import Icon from '../../utils/Icon';
const cardWidth = sizes.width / 3;
const cardHeight = 120;
const CartItem = ({list}) => {
return (
<View style={{flex: 1}}>
{list.map((item, index) => {
return (
<View style={{height: '20%'}} key={index}>
<View
style={{
marginLeft: spacing.l,
marginRight: spacing.l,
backgroundColor: 'white',
height: '90%',
borderRadius: sizes.radius,
}}>
<View style={{flexDirection: 'row'}}>
<View style={{justifyContent: 'center'}}>
<Image
style={{
width: cardWidth,
height: cardHeight,
borderRadius: 12,
marginLeft: spacing.m,
}}
resizeMode="stretch"
source={item.image}
/>
</View>
<View style={{marginTop: spacing.m, marginLeft: spacing.l}}>
<Text style={{marginBottom: 8}}>{item.title}</Text>
<Text>{item.price}</Text>
</View>
</View>
</View>
</View>
);
})}
</View>
);
};
export default CartItem;
this is my desired image
Use alignItems instead of justifyContent.
alignItems controls how children are aligned within the cross axis of their container, so in the case of a row within the vertical axis. justifyContent applies to the main axis, so the horizontal for a row.
you can give justifyContent to the upper view
<View style={{flexDirection: 'row', justifyContent:"center"}}>
<View style={{justifyContent: 'center'}}>
<Text style={{marginBottom: 8}}>Image</Text>
</View>
</View>

How do i prevent the keyboard from pushing my view up in react native?

I am building a registration form in React Native. I have this view.
When keyboard is showing it is pushing my form and image over my title view like this.
What should i do so that it my view doesnot lose its shape. I already tried scrollview and keyboard avoiding view but they are not helping.
Here is my code.
<View style={styles.container}>
<View style={styles.headingContainer}>
<Text style={styles.headingText}>Sign Up</Text>
</View>
<View style={styles.form}>
<View style={{ marginTop: 5, width: '100%', padding: 10 }}>
<Input
name="name"
placeholder="Name"
label="Name"
/>
<View style={styles.buttons}>
<Button onPress={handleSubmit}>
{isLogin ? 'Log In' : 'Sign Up'}
</Button>
</View>
</View>
</View>
<View style={styles.logoCon}>
<Image style={styles.logo} source={Logo} />
</View>
</View>
);
}
export default AuthForm;
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
},
headingContainer: {
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '40%',
backgroundColor: Colors.primary800,
marginBottom: '-22%',
},
form: {
backgroundColor: Colors.primary100,
justifyContent: 'center',
alignItems: 'center',
height: 'auto',
width: '100%',
borderTopLeftRadius: 80,
},
logoCon: {
alignSelf: 'center',
height: 100,
width: 100,
marginTop: 'auto',
marginBottom: -15,
},
});
Update: I have solve the above issue, but now I am facing another issue i.e. I have to hide keyboard everytime i try to input text in any of the lower inputs. Also it is pushing my top view up inside the screen. NO scrollview is working. I have tried KeyboardAvoidingView, ScrollView, Animation, KeyboardAwareScrollView so far but got no luck.
PS: I know UIs are different. Its because i have completed the UI and this is the last thing i need to work on.
I have managed to overcome this issue using this npm package: react-native-keyboard-aware-scroll-view
npm install --save react-native-keyboard-aware-scroll-view
Then in your component, the basic usage is like below
return (
<Fragment>
<SafeAreaView style={{flex: 1}}>
<KeyboardAwareScrollView keyboardShouldPersistTaps='always'>
<View style={{flex: 1}}>
//The content
</View>
</KeyboardAwareScrollView>
</SafeAreaView>
</Fragment>
);
If you have a modal, I'd suggest you to use it like that
<Modal
animationType="slide"
transparent={true}
visible={this.state.search_modal_visible}
>
<KeyboardAwareScrollView contentContainerStyle={{flexGrow: 1}}>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
//The content
</View>
</KeyboardAwareScrollView>
</Modal>
In your AndroidManifest.xml, please be sure the line below exists as an attribute for activity tag
<activity
android:windowSoftInputMode="adjustResize"
You can hide keyboard whenever you want like that in your code
Keyboard.dismiss();
The problem here is that you have in your AndroidManifest.xml:
windowSoftInputMode="adjustResize";
Change it to:
windowSoftInputMode="adjustPan"
Note: after this change you'll need run ./gradlew clean in android folder and react-native run-android in your project directory
Try to use KeyboardAvoidingView of react native
I hade the same issue, I used this to just hide the views I don't want to see whenever the keyboard is opened: https://github.com/TIKramer/react-native-hide-onkeyboard
If you found another solution please let me know.

Buttons not at the same place in Android and iOS

I have buttons that are not located at the same place in iOS and Android.
In Android they are at the middle bottom of the screen (it is what I expect) but in iOS they are at the top of the screen.
Do you know how I can put buttons in iOS at the same place as Android ?
import { Button } from 'react-native-elements';
...
<ImageBackground
key={`image${i}`}
source={{uri: image}}
style={{ width: deviceWidth, justifyContent:'center', alignItems: 'center', flex: 1 }}>
<View style={{flex: 1}}></View>
<Text style={{flex: 1}}> {textToDisplayEnglish[i]} </Text>
<Button
title={textA[i]}
style={{flex: 1}}
type={typeButton[i]}
onPress={() => this.triggerAction(i)}
/>
<View style={{flex: 1}}></View>
</ImageBackground>
you have too many flex:1. It'd be best to avoid using too many of them,unless you need to. try something like this:
import { Button } from 'react-native-elements';
...
<ImageBackground
key={`image${i}`}
source={{uri: image}}
style={{ width: deviceWidth, justifyContent:'center', alignItems: 'center', flex: 1 }}>
<Text> {textToDisplayEnglish[i]} </Text>
<Button
title={textA[i]}
type={typeButton[i]}
onPress={() => this.triggerAction(i)}
/>
</ImageBackground>
hope it helps!

How to position a View at the bottom of a ScrollView?

I would like to create a screen with a ScrollView with some input fields in it, and a Button (actually 2 buttons in a normal View) at the bottom of the screen. This should be pretty easy, BUT, I want to position my button at the very bottom of the screen even if there isn't enough element in the ScrollView to fill the whole screen. I could use absolute positioning, BUT my ScrollView can be bigger (higher) then my screen, and in this case, the button should be at the end of the ScrollView. (So it would be out of the screen, which means the user should scoll down to see the button).
I've tried a lot of things, but the Button always comes right after the other elements inside the ScollView.
In the picture the scrollview has a blue border, and the normal view which contains the buttons has black border.
Any suggestion is appreciated.
Found the best solution.
The key is the contentContainerStyle property (doc: https://facebook.github.io/react-native/docs/scrollview#contentcontainerstyle). "These styles will be applied to the scroll view content container which wraps all of the child views. "
After setting flexGrow: 1, justifyContent: 'space-between', flexDirection: 'column' in contentContainerStyle, one can set justifyContent: 'flex-start' for the upper container view with the text, and justifyContent: 'flex-end' for the lower container view with the buttons.
<ScrollView
contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between', flexDirection: 'column' }}
style={{ backgroundColor: 'white', paddingBottom: 20 }}
>
<View style={{ flex: 1, justifyContent: 'flex-start' }}>
<Text>Some text with different length in different cases, or some input fileds.</Text>
</View>
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<View>
<TouchableOpacity style={[commonStyles.greenButton, styles.buttonPadding]}>
<Text style={commonStyles.greenButtonTitle}>Next</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity style={styles.cancelButtonContainer}>
<Text style={styles.cancelButton}>Cancel</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>;
<ScrollView
contentContainerStyle={{
flexGrow: 1,
justifyContent: 'flex-end',
}}>
</ScrollView>
I found a workaround for this.
The main idea is to set the height of the View with the texts and input fields to match exactly the height of the screen minus the View which contains the buttons.
The challenge is to calculate this height. Abhishek Kumar's answer helped me (https://stackoverflow.com/a/41398953/4109477) See my code below:
import { View, ScrollView, Text, TouchableOpacity, Dimensions } from 'react-native';
const screenHeight = Dimensions.get('window').height;
class MyClass extends React.Component {
constructor(props) {
super(props);
this.state = {buttonViewHeight: 0};
}
find_dimesions(layout){
this.setState({buttonViewHeight: layout.height});
}
render() {
return (
<View style={{minHeight: screenHeight, flex: 1, alignItems: 'center'}}>
<ScrollView style={{minHeight: screenHeight}}>
<View style={{minHeight: screenHeight}}>
<View style={{minHeight: screenHeight - this.state.buttonViewHeight, borderWidth: 2, borderColor: 'red', alignItems: 'center', flex: 1}]}>
<Text>Some text with different length in different cases, or some input fileds.</Text>
</View>
<View onLayout={(event) => { this.find_dimesions(event.nativeEvent.layout) }} style={{paddingBottom: 50, flex: 1, borderWidth: 2, borderColor: 'green'}}>
<TouchableOpacity
style={[commonStyles.greenButton, styles.buttonPadding]} >
<Text style={commonStyles.greenButtonTitle}>Next</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.cancelButtonContainer} >
<Text style={styles.cancelButton}>Cancel</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>
</View>
}
}
On the picture below you can see the result
This solution will cause an animation like effect as the view renders multiple times, because of the changing of the View's height. The button's View "fade in" as you open the screen.
If you find a better solution please let me know!

ListItem lost its content after applying alignItems: 'center' to the parent view

I only applied alignItems: 'center' to the View, and lost all content of ListItems.
Any ideas how to fix? Thanks a lot.
This is because we are setting alignment center of parent view. Don't set alignment center of parent view. Create another child view and set alignment center of that.
<View style={{ flex: 1 }}>
<View style={{ alignItems: 'center' }}>
{/*... QR code image */
</View>
<View>
{/*... list view*/}
</View>
</View>
Or you can also set alignSelf instance of alignItems
<View style={{ flex: 1 }}>
<View style={{ alignSelf: 'center' }}>
{/*... QR code image */
</View>
<View>
{/*... list view*/}
</View>
</View>
alignSelf set position for only that element. It will not reflect other element which is child of same parent.