Iam developing a mobile app using React Native and Native Base with react-native-vector-icons as well. And Iam trying to add some inline label icons to my login-form, but for some reason they keep getting cut off on the right side.
I have tried taking away the padding from the Item, Icon, and Inputs but the icons are still cut off.
I then went to change the font size of the icons themselves and that still did nothing.
Does anyone know why this is caused. I've uploaded an image of my screen and the code for it as well.
Any help on this matter would be greatly appreciated.
Here is a picture of my app emulated on my Android LG V30+App Screenshot
import React, { Component } from "react";
import { Image, View, ImageBackground } from "react-native";
import {
Container,
Header,
Title,
Body,
Content,
Thumbnail,
Card,
CardItem,
Footer,
FooterTab,
Button,
Left,
Right,
Icon,
Form,
Item,
Input,
Text,
InputGroup,
List,
ListItem
} from "native-base";
class LoginScreen extends Component {
render() {
return (
<Container>
<Header>
<Left>
<Button transparent>
<Icon
name="menu"
onPress={() =>
this.props.navigation.navigate("DrawerOpen")
}
/>
</Button>
</Left>
<Body>
<Title>Run For A Reason</Title>
</Body>
<Right />
</Header>
<Content
contentContainerStyle={{ flex: 1, flexDirection: "column" }}
>
<View style={{ flex: 1 }}>
<ImageBackground
source={require("../../img/background.jpg")}
style={{ flex: 1 }}
>
<View
style={{
justifyContent: "center",
alignItems: "center"
}}
>
<Image
source={require("../../img/logo.jpg")}
style={styles.logoStyle}
/>
</View>
<View
style={{
paddingTop: 150,
paddingLeft: 20,
paddingRight: 20
}}
>
<Form style={{ backgroundColor: "white" }}>
<Item
style={{
marginLeft: 0,
paddingLeft: 0
}}
>
<Icon
style={styles.iconStyles}
name="mail"
/>
<Input
style={{ paddingLeft: 0 }}
placeholder="Email"
/>
</Item>
<Item>
<Icon
style={styles.iconStyles}
name="lock"
/>
<Input placeholder="Password" />
</Item>
</Form>
</View>
<View
style={{
flexDirection: "row",
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
>
<Button
primary
style={{ borderRadius: 15, marginTop: 20 }}
>
<Text>Login</Text>
</Button>
</View>
</ImageBackground>
</View>
</Content>
</Container>
);
}
}
const styles = {
iconStyles: {
color: "blue",
paddingRight: 0
},
logoStyle: {
paddingTop: 20,
width: 250,
height: 200,
alignItems: "center",
justifyContent: "center",
resizeMode: "contain"
}
};
Replace Icon with Button containing Icon and apply your style on Button component.
<Button iconLeft>
<Icon name='arrow-back' />
</Button>
can you try this
<Form style={{ backgroundColor: 'white' }}>
<Item>
<Icon style={styles.iconStyles} name='mail' />
<Input placeholder='Email' />
</Item>
<Item>
<Icon style={styles.iconStyles} name='lock' />
<Input placeholder='Password' />
</Item>
</Form>
I fixed this by increasing the width in percentages on the icon as such:
style={{width: '115%'}}
I was having the same issue because of fontSize style.
Don't use the fontSize style, instead use the size and boxSize props of the Icon component.
<Icon size={10} boxSize={20} as={MaterialIcons} name="share" />
Related
I am building a react native application and I use scrollview for some contents but it is not scrolling I cannot figure out why.
I try a lot of things, adding flex: 1 everywhere but none of these is working.
Thank you in advance for your help.
<KeyboardAwareScrollView contentContainerStyle={authStyles.container}>
<Layout isBackArrow={true}>
<BottomLayout>
<Header fontSize={20}>
<Text>Nous sommes</Text> {'\n'}
<Text style={authStyles.headerBold}>
Ravis de te revoir!
</Text>
{'\n'}
<Caption>Je me connecte via:</Caption>
</Header>
<View style={authStyles.socialIconView}>
<SocialIcon type="facebook" onPress={onFacebookLogin} />
<SocialIcon type="google" />
<SocialIcon
type="apple"
onPress={onAppleButtonPress}
style={{ backgroundColor: COLORS.BLACK }}
/>
</View>
<View style={authStyles.orView}>
<Header fontSize={15}>
<Text style={authStyles.headerBold}>Ou</Text>
{'\n'}
<Caption>
Je saisis mon email et mot de passe
</Caption>
</Header>
</View>
<View style={authStyles.inputView}>
<CustomInput
label="Email"
icon
iconName="envelope"
iconFamily="font-awesome"
onChange={text => setEmail(text)}
/>
<CustomInput
label="Mot de passe"
icon
iconName="lock"
iconFamily="entypo"
onChange={text => setPassword(text)}
password
/>
<CustomButton
title="Mot de passe oublié ?"
clear
onPress={open}
/>
</View>
</BottomLayout>
</Layout>
</KeyboardAwareScrollView>
Layout component:
<View style={layoutStyles.background}>
{isBackArrow && <BackArrow onPress={onBackArrowPress} />}
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{
flex: 1,
}}
>
{children}
</ScrollView>
</View>
layout style:
background: {
backgroundColor: COLORS.BRAND_ORANGE_OPACITY_2,
width: '100%',
height: '100%',
flex: 1,
},
BottomLayout Component:
<View style={layoutStyles.bottomLayout}>{children}</View>;
bottom layout style:
bottomLayout: {
backgroundColor: COLORS.BRAND_ORANGE,
position: 'absolute',
bottom: 0,
height: '75%',
width: '100%',
borderTopLeftRadius: 70,
borderTopRightRadius: 70,
paddingTop: 60,
flex: 1,
},
keyboardAwareScrollView contentContainerStyle:
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
},
Thanks in advance.
KeyboardAwareScrollView gives you a ScrollView already, you don't need to add another one inside of it.
Remove the ScrollView from Layout or remove the KeyboardAwareScrollView.
React Native Nested ScrollView Can`t Scroll on Android Device
Also don't use flex: 1 in contentContainerStyle, instead use minHeight: '100%' (why?) if you want it to be full screen even when there is not enough content in it.
My problem is as follows, I am passing a large string to one of the Picker items, because of this, the text is not displaying completely on the screen.
I tried to set a fixed width but this solution did not work.
<View style={styles.container}>
<Image source={logo} />
<View style={styles.bodyContainer}>
<Text style={styles.message}>
Para que possamos verificar se Sr. (a) está apto (a) para receber o benefício da
previdência social, por favor, nós informe a categoria do usuário.
</Text>
<View style={styles.pickerContainer}>
<Picker
style={styles.picker}
mode="dialog"
selectedValue={this.state.userCategory}
onValueChange={(itemValue, itemIndex) => {
if (itemValue !== '') {
this.setState({userCategory: itemValue});
}
}}>
<Picker.Item
color="#979898"
label="Por favor, selecione o tipo do benefício..."
value=""
/>
<Picker.Item color="#979898" label={data.categories[0]} value="0" />
<Picker.Item color="#979898" label={data.categories[1]} value="1" />
<Picker.Item color="#979898" label={data.categories[2]} value="2" />
</Picker>
</View>
const styles = StyleSheet.create({
pickerContainer: {
width: '100%',
height: 50,
borderColor: '#707070',
borderWidth: 1,
borderRadius: 10,
overflow: 'hidden'
},
picker: {
width: '100%',
height: 50,
color: '#979898',
flexDirection: 'column'
},
});
I wish that if the text was larger than the maximum width there would be a line break.
image of the problem:
You can set your View component with flexDirection: "row" and your Text component style with flexWrap: "wrap":
<View style={{ flexDirection: 'row', alignItems: "center" }}>
<Text style={{ flexWrap: 'wrap', flex: 1}}>{item.nome}</Text>
</View>
Giving fixed width will automatically truncate your text.
Try giving it flex:1 and also text comes with a prop of numberOfLines try using that.
Moreover, if you can give padding to text to make it aligned in the view.
Dont give it fixed width or fixed height.
I'm creating a login, and to solve the problem with the virtual keyboard covering my text inputs I'm using KeyboardAvoidingView. I thought that the logo would animate nicely since I define both the form and the logo as flex: 1 (shrink/grow as much as possible in the available space) Since opening a keyboard diminishes the available space on the screen, the logo does change, but shrinks too much and then an overlap occurs. What I am missing?
This is my LoginScreen:
import React, { Component } from 'react'
import { Image, StyleSheet, View, KeyboardAvoidingView, Button } from 'react-native'
import FormTextInput from '../components/FormTextInput'
class LoginScreen extends Component {
state = { email: '', password: '' }
handleEmailUpdate = email => {
this.setState({ email })
}
handlePasswordUpdate = password => {
this.setState({ password })
}
handleLoginPress = () => {
console.log('Login button pressed')
}
render() {
return (
<KeyboardAvoidingView style={styles.container} behavior="padding">
<Image style={styles.logo} source={require('../assets/images/test.png')} />
<View style={styles.form}>
<FormTextInput
value={this.state.email}
onChangeText={this.handleEmailChange}
placeholder="Email"
autoCorrect={false}
keyboardType="email-address"
returnKeyType="next"
/>
<FormTextInput
placeholder="Password"
value={this.state.password}
onChangeText={this.handlePasswordChange}
secureTextEntry
returnKeyType="done"
/>
<Button title="LOGIN" onPress={this.handleLoginPress} />
</View>
</KeyboardAvoidingView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-between',
},
logo: {
flex: 1,
width: '80%',
resizeMode: 'contain',
alignSelf: 'center',
},
form: {
flex: 1,
justifyContent: 'center',
width: '80%',
},
})
export default LoginScreen
*EDIT: after adding the line android:windowSoftInputMode="adjustPan", the keyboard overlaps the login button:
Use this is your android manifest
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan" //add this line
android:exported="true">
try this it will solve this problem
try this.
{Platform.OS === 'ios' ?
<KeyboardAvoidingView style={styles.container} behavior="padding">
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{paddingVertical: 10}}
keyboardShouldPersistTaps='handled'>
<Image style={styles.logo} source={require('../assets/images/test.png')} />
<View style={styles.form}>
<FormTextInput
value={this.state.email}
onChangeText={this.handleEmailChange}
placeholder="Email"
autoCorrect={false}
keyboardType="email-address"
returnKeyType="next"
/>
<FormTextInput
placeholder="Password"
value={this.state.password}
onChangeText={this.handlePasswordChange}
secureTextEntry
returnKeyType="done"
/>
<Button title="LOGIN" onPress={this.handleLoginPress} />
</View>
</ScrollView>
</KeyboardAvoidingView>
: <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{paddingVertical: 10}}
keyboardShouldPersistTaps='handled'>
<Image style={styles.logo} source={require('../assets/images/test.png')} />
<View style={styles.form}>
<FormTextInput
value={this.state.email}
onChangeText={this.handleEmailChange}
placeholder="Email"
autoCorrect={false}
keyboardType="email-address"
returnKeyType="next"
/>
<FormTextInput
placeholder="Password"
value={this.state.password}
onChangeText={this.handlePasswordChange}
secureTextEntry
returnKeyType="done"
/>
<Button title="LOGIN" onPress={this.handleLoginPress} />
</View>
</ScrollView>
}
and style is
const styles = StyleSheet.create({
container: {
flex: 1, paddingVertical: 30,
alignItems: 'center', justifyContent: 'center',
backgroundColor: '#FFFFFF',
},
logo: {
flexGrow: 1,
width: '80%',
resizeMode: 'contain',
alignSelf: 'center',
},
form: {
flexGrow: 1,
justifyContent: 'center',
width: '80%',
},
});
I have used Content to achieve the vertical scrolling and tried using ScrollView as well. But nothing works with Card component in native-base. This behavior was shown when testing in an Android emulator.
Following is my working,
render() {
return (
<Container>
<Header style={{backgroundColor: Colors.headerBackground, justifyContent: 'center', marginTop: '4%'}}>
<Left>
<Button transparent onPress={this.handleBackButtonClick} small={true}>
<Icon name='arrow-back' size={30} color={Colors.textWhite}/>
</Button>
</Left>
<Body>
<Title style={{
fontSize: 20,
fontWeight: '200'
}}>Events</Title>
</Body>
</Header>
<Content>
{ (this.state.events).map(event => { return (
<Card key={event.title} style={{ marginTop:'2%', marginLeft:'2%', marginRight:'2%', marginBottom:'2%'}}>
<CardItem>
<Image source={{uri:event.uri}}
style={{height:200, width: null, flex:1}}/>
</CardItem>
<CardItem>
<Left>
<View style={{height: '50%'}}>
<Text style={{color: Colors.calenderMonth, fontSize: 15}}>Jun</Text>
<Text style={{fontSize: 15}}>15</Text>
</View>
</Left>
<Body style={{alignSelf: 'flex-start', marginLeft: '-50%'}}>
<Text style={{fontSize: 20, fontWeight: 'bold'}}>{event.title}</Text>
<Text note>{event.desc}</Text>
</Body>
</CardItem>
</Card>
) } ) }
</Content>
</Container>
);
}
Any ideas? Thanks
Set flexGrow: 1 to contentContainerStyle prop of the Content component:
<Content contentContainerStyle={{ flexGrow: 1 }}>
This worked for me after many hours of struggling with the issue.
I had the same issue with one of my project. I realize that the <Card> wasn't scrolling even after i place it in a <ScrollView> because it was within the <Container>.
I solved it by creating a separate Component with the <Card> within the <ScrollView> and import it.
Example:
render() {
return (
<ScrollView>
<Card>
<CardItem>
</CardItem>
</Card>
</ScrollView>
);
}
Import it:
render() {
return (
<Container>
<Content>
<ScrollingCardExample />
</Content>
</Container>
);
}
Use <ScrollView> instead of <Content> and make sure u have enough contents to test scrolling.
tried your code with some data. Working fine for me.
import React, { Component } from 'react';
import { Image } from "react-native";
import { Container, Header, Left, Body, Button, Icon, Title, Content, Card, CardItem, View, Text } from 'native-base';
export default class App extends Component {
state = { events: [1, 2, 3, 4, 5] }
render() {
return (
<Container>
<Header style={{ justifyContent: 'center', marginTop: '4%' }}>
<Left>
<Button transparent onPress={this.handleBackButtonClick} small={true}>
<Icon name='arrow-back' size={30} color="white" />
</Button>
</Left>
<Body>
<Title style={{
fontSize: 20,
fontWeight: '200'
}}>Events</Title>
</Body>
</Header>
<Content>
{(this.state.events).map(event => {
return (
<Card key={event} style={{ marginTop: '2%', marginLeft: '2%', marginRight: '2%', marginBottom: '2%' }}>
<CardItem>
<Image source={{ uri: "https://nativebase.io/assets/img/front-page-icon.png" }}
style={{ height: 200, width: null, flex: 1 }} />
</CardItem>
<CardItem>
<Left>
<View style={{ height: '50%' }}>
<Text style={{ fontSize: 15 }}>Jun</Text>
<Text style={{ fontSize: 15 }}>15</Text>
</View>
</Left>
<Body style={{ alignSelf: 'flex-start', marginLeft: '-50%' }}>
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>Title</Text>
<Text note>Description</Text>
</Body>
</CardItem>
</Card>
)
})}
</Content>
</Container>
);
}
}
Gif
can't display floating button over webview on android.
ios work fine, on android doesn't show.
render function:
<View style={{ flex: 1}}>
<View style={{position:'absolute',right:0,marginTop:90,marginRight:10,zIndex:1,height:50,width:50}}>
<TouchableHighlight style={styles.addButton}
underlayColor='#ff7043' onPress={()=>{console.log('pressed')}}>
<Text style={{fontSize: 50, color: 'black'}}>+</Text>
</TouchableHighlight>
</View>
<WebView
source={require('./index.html')}
style={{marginTop:0}}
scalesPageToFit={Platform.OS !== 'ios'}
onMessage={this.onMessage}
postMessage={"Hello from RN"}
/>
</View>
css:
const styles = StyleSheet.create({
addButton: {
backgroundColor: '#ff5722',
borderColor: '#ff5722',
borderWidth: 1,
height: 100,
width: 100,
borderRadius: 50,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
bottom: 20,
right:20,
shadowColor: "#000000",
shadowOpacity: 0.8,
shadowRadius: 2,
shadowOffset: {
height: 1,
width: 0
}
}
});
How can I display a button over web view on android ?
The solution is pretty simple, put the Button View code under/after the WebView code
<View style={{ flex: 1}}>
<WebView
source={require('./index.html')}
style={{marginTop:0}}
scalesPageToFit={Platform.OS !== 'ios'}
onMessage={this.onMessage}
postMessage={"Hello from RN"}
/>
<View style={{position:'absolute',right:0,marginTop:90,marginRight:10,zIndex:1,height:50,width:50}}>
<TouchableHighlight style={styles.addButton}
underlayColor='#ff7043' onPress={()=>{console.log('pressed')}}>
<Text style={{fontSize: 50, color: 'black'}}>+</Text>
</TouchableHighlight>
</View>
</View>
If for some reason you can't put it under the WebView, adding a elevation style prop higher than the WebView's, alongside the zIndex style prop will work for you.
That's because the zIndex property is quite broken on Android (see the dedicated issues). To compensate for it, you must invert the rendering order of your container's children.
This can be done either by rendering the button after the WebView:
<View style={{ flex: 1 }}>
<WebView />
<View style={{ styles.button }} />
</View>
Or by reversing the display order in your container, using flexDirection:
<View style={{ flex: 1, flexDirection: 'column-reverse' }}>
<View style={{ styles.button }} />
<WebView />
</View>
Note that you can also use the android-specific elevation API. This will act as a reliable z-index and is the only way to display a shadow on Android.