Wrap text inside view without overflowing - react-native

I am new to react native. I am trying to set the text in a view, but the text is overflowing outside the view like in the image below. Tried flexWrap:'wrap and flexShrink:1 but it is also not working. I have implemented as follows:
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => navigate('BlogDetails', item)}>
<Card style={{flexDirection:'row',flexShrink:1}}>
<CardSection>
<View style={styles.thumbnailContainerStyle}>
<Image
style={styles.thumbnailStyle}
source={{ uri: item.imagepath }}
/>
</View>
<CardSection>
<View style={styles.headerContentStyle}>
<Text numberOfLines={5} style={styles.headerTextStyle}>{item.news_title}</Text>
{/* <Text>{item.blog_description}</Text> */}
</View>
</CardSection>
</CardSection>
</Card>
</TouchableOpacity>
)}
keyExtractor={(item, index) => index.toString()}
>
</FlatList>
</View>
My style :
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
minHeight: 1,
minWidth: 1,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginRight: 10
},
headerContentStyle: {
flexDirection: 'column',
flexWrap:'wrap',
flexShrink:1,
justifyContent: 'center',
alignItems: 'flex-start'
},
thumbnailStyle: {
width: 130,
height: 130,
resizeMode:"contain"
},
imageStyle: {
height: 100,
flex: 1,
width: null
},
cardStyle:{
width:'100%',
height:200,
},
headerTextStyle:{
fontSize:20,
flexWrap: 'wrap',
flexShrink: 1
},
infoText: {
fontSize: 14
}
});

Try this :
Add flexShrink:1 in parent wrapper and in text component do flex:1 and flexWrap:'wrap'

use only flexWrap : 'wrap' for wrap your text use this css for your view and text
headerContentStyle: {
flexWrap : 'wrap'
},
headerTextStyle:{
fontSize:20,
},

Related

how to use inline flex property in react native

Here's what I'm trying to achieve:
I want to display inline all these three elements inside each Block.
Here's what I have done so far:
export default function App() {
const cheers = [
'cheers',
'high five'
]
return (
<Block style={{ flex: 1,
flexDirection: "row",
alignContent: "space-between",
marginTop: 50}}
>
<Block style={{ flex: 2, justifyContent: 'center'}}>
<Text style={{marginRight: 5}}>Send a</Text>
</Block>
<Block style={[styles.dropdownsRow, {flex: 2}]}>
<SelectDropdownMenu
data={cheers}
onSelect={(selectedItem, index) => {
console.log(selectedItem, index);
}}
defaultButtonText={'Cheers'}
buttonTextAfterSelection={(selectedItem, index) => {
return selectedItem.name;
}}
rowTextForSelection={(item, index) => {
return item.name;
}}
buttonStyle={styles.dropdown1BtnStyle}
buttonTextStyle={styles.dropdown1BtnTxtStyle}
renderDropdownIcon={isOpened => {
return <FontAwesome name={isOpened ? 'chevron-up' : 'chevron-down'} color={'#8898aa'} size={10} />;
}}
dropdownIconPosition={'right'}
dropdownStyle={styles.dropdown1DropdownStyle}
rowStyle={styles.dropdown1RowStyle}
rowTextStyle={styles.dropdown1RowTxtStyle}
/>
</Block>
<Block style={{flex: 2, justifyContent: 'center' }}>
<Text style={{marginLeft: 5, marginRight: 5}}>to</Text>
</Block>
<Block style={{ justifyContent: 'center'}}>
<Input
right placeholder="Type your custom question here."
iconContent={<Block />}
/>
</Block>
);
}
const styles = StyleSheet.create({
dropdownsRow: {justifyContent: 'center', maxWidth: '10%'},
dropdown1BtnStyle: {
height: 45,
backgroundColor: '#edeff2',
borderRadius: 5,
borderColor: '#444',
},
dropdown1BtnTxtStyle: {color: '#8898aa', textAlign: 'left', fontSize: 14},
dropdown1DropdownStyle: {backgroundColor: '#EFEFEF'},
dropdown1RowStyle: {backgroundColor: '#EFEFEF', borderBottomColor: '#C5C5C5'},
dropdown1RowTxtStyle: {color: '#444', textAlign: 'left'}
});
I'm new to react native and don't know how flex property works.
Here's my sample output:
The whole code found here whole code
You can use Yoga layout website to find your desired UI and then migrate your styles to your code.

A lot of white space between items of a flat list in react native

I am trying to create a flat list in react native that displays an image as many times as the length of an array called "bools" (later, I will also display contents of bools in the flatlist). While I am able to create and display the flatlist, there is a lot of space between each item and above & below the first and last items, respectively. I can’t remove top and bottom margins completely because I want to add other elements above and below the flatlist. Other than this, I have tried every possible thing I could find online, but nothing is working.
Flat List:
<View style={{ marginTop: "10%", marginBottom: "20%" }}>
<FlatList
// contentContainerStyle={{ paddingBottom: "40%", paddingTop: "5%" }}
style={{ paddingBottom: "3%" }}
data={bools}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => {
return (
<SafeAreaView style={styles.itemContainer}>
<View style={styles.iconStyle}>
<Image
source={someImage}
style={{ aspectRatio: 1, height: "8%" }}
/>
</View>
</SafeAreaView>
);
}}
/>
</View>
Styles:
styles = StyleSheet.create({
itemContainer: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
height: "30%",
marginVertical: "3%",
//paddingTop: "1%",
//paddingBottom: "1%"
},
iconStyle: {
borderWidth: 1,
padding: 10,
borderRadius: 50,
borderColor: "#555",
marginRight: "5%",
resizeMode: "contain",
},
});
})
Thank you!
You can use SafeAreaView out rather then wrapping with all items And you can give style safearea as per your requirement.
<SafeAreaView>
<View style={{ marginTop: "10%", marginBottom: "20%" }}>
<FlatList
// contentContainerStyle={{ paddingBottom: "40%", paddingTop: "5%" }}
style={{ paddingBottom: "3%" }}
data={bools}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => {
return (
<View style={styles.itemContainer}>
<View style={styles.iconStyle}>
<Image
source={someImage}
style={{ aspectRatio: 1, height: "8%" }}
/>
</View>
</View>
);
}}
/>
</View>
</SafeAreaView>
You have the spacing between your elements because of your styling properties.
In your FlatList just remove these properties and the space of above & below the first and last items will be gone. You have to remove these lines.
contentContainerStyle={{
paddingBottom: "40%",
paddingTop: "5%"
}}
style={{paddingBottom: '3%'}}
Similary the space between the items are due to the margin in the itemContainer of Styles Object. just remove this line and then spacing between the items will be gone as well
marginVertical: "3%"
Your Final Code should be something like this
<View>
<FlatList
data={bools}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => {
return (
<SafeAreaView style={styles.itemContainer}>
<View style={styles.iconStyle}>
<Image style={{aspectRatio: 1, height: '8%'}} />
</View>
</SafeAreaView>
);
}}
/>
</View>
const styles = StyleSheet.create({
itemContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: '30%',
backgroundColor: 'red',
//paddingTop: "1%",
//paddingBottom: "1%"
},
iconStyle: {
borderWidth: 1,
padding: 10,
borderRadius: 50,
borderColor: '#555',
marginRight: '5%',
resizeMode: 'contain',
backgroundColor: 'blue',
},
});

React Native Button Not Visible Android

Button is not visible in the android.
Render Method:
render() {
return (
<View style = { styles.container }>
<View style = { styles.form }>
<Image source={require('../../assets/icon.png')} style = {styles.loginIcon}/>
<View style = { styles.form }>
<TextInput style={ styles.input } onChangeText={(username) => this.setState({username})} placeholder="Username"/>
<TextInput style={ styles.input } onChangeText={(password) => this.setState({password})} placeholder="Password"/>
<View style={ styles.buttonView }>
<Button title="Login" color="#197DC1" style={ styles.primaryBttn } onPress={this.validateCredentialsAndLogin.bind(this)}/>
</View>
<Text>
Forgot Password?
</Text>
</View>
</View>
</View>
);
}
CSS:
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ECF0F1'//#F5FCFF
},
form :{
flex:1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
flexDirection: 'column',
marginTop: '25%',
marginBottom:'25%',
paddingTop:'10%',
width:'90%',
height:'40%'
},
input:{
height:40,
marginBottom:10,
borderBottomColor: 'black',
width:'100%'
},
loginIcon:{
width:80,
height:80,
},
buttonView:{
flex:1,
width:'100%',
height:50
}
Even though there is flex for parent and height and color for button still not able to view button.
PS: I am new to react-native correct me If I am wrong with the styles or anything else.
Looks like issue is with your styling. You can see your button simply replacing your form style with following:
form:{
flex:1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
flexDirection: 'column',
width:'90%',
height:'40%'
},
You should first learn how to style using flexbox(link).

ListEmptyComponent not taking full screen with flex 1 in React Native Section List

So I am using React Native Section List and following is my Code of ListEmptyContent
// define your styles
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
marginLeft: 10,
marginRight: 10,
},
imageStyle: {
width: 140,
height: 120,
},
titleStyle: {
fontSize: 14,
color: '#363a45',
},
subTitleStyle: {
fontSize: 12,
color: '#898d97',
},
});
// create a component
const GPEmtptyTransaction = ({ firstLine, secondLine }) => {
return (
<View style={styles.container}>
<Image source={images.emptyTransactionIcon} style={styles.imageStyle} />
<Text style={styles.titleStyle}>{firstLine}</Text>
<Text style={styles.subTitleStyle}>{secondLine}</Text>
</View>
);
};
But when EmptyTemplate is rendered it is rendered on Top and not stretching to full screen.
This works for me, apply flexGrow: 1 to contentContainerStyle
<FlatList
data={this.props.operations}
contentContainerStyle={{ flexGrow: 1 }}
ListEmptyComponent={<EmptyPlaceHolder />}
renderItem={this.renderOperationItem} />
For me what worked was adding some styles to the contentContainerStyle as well:
contentContainerStyle={{ flex: 1, justifyContent: 'center' }}
The SectionList complete setup on my end was:
<SectionList
showsVerticalScrollIndicator={false}
sections={filteredData}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
initialNumToRender={15}
contentContainerStyle={{ flex: 1, justifyContent: 'center' }}
ListEmptyComponent={() => (
<EmptyListComponent
icon={<Document />}
message={'Your roster is empty'}
/>
)}
/>
You can add contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} prop to FlatList
I got success with the simple trick as below
import { Dimensions } from "react-native";
const SCREEN_HEIGHT = Dimensions.get("window").height;
than I declare the empty component
_listEmptyComponent = () => {
return (
<View
style={{
justifyContent: "center",
alignItems: "center",
height: SCREEN_HEIGHT , //responsible for 100% height
backgroundColor: "#ddd"
}}
>
<Text
style={{
justifyContent: "center",
alignItems: "center",
fontSize: 20
}}
>
No Contracts Found
</Text>
</View>
);
And at last Flatlist look like :
<FlatList
extraData={this.props.contracts}
data={this.props.contracts}
ListEmptyComponent={this._listEmptyComponent.bind(this)}
renderItem={({ item }) => (
<Text>{item.contractName}>
<Text/>
)}
keyExtractor={(item, index) => item.id}
/>

Align 3 dynamic views in one row

i want to align 3 Views in a row:
|Icon| |Title| |Buttons|
The Title can be more than one line. The buttons are 0-3 Buttons, so their width is unknown to me.
Now the problem is, if I got more than one line in the title the buttons are cut off. How can i solve this and make sure the buttons are always on the screen and the title just has the space that is left?
On this screenshot 2 listitems are visible. Both should have 3 buttons on the right, but with the long title in the second row, the buttons are cut off
render() {
return (
<TouchableHighlight style={styles.view} underlayColor={'#eee'} onPress={this.props.navigateToDetails}>
<View style={{flex: 1}}>
<View style={styles.header}>
<View style={styles.headerTitle}>
<MaterialIcons style={styles.icon} name={"worker"}/>
<MentionsText style={styles.title}
>
{this.props.siteVisitNote.title}
</MentionsText>
</View>
<View style={styles.buttons}>
<FontAwesomeIcons style={styles.icon} name="tag"/>
{Utils.objectExists(this.props.siteVisitNote.attachments) || true ?
<FontAwesomeIcons style={styles.icon} name="paperclip"/> : null}
{Utils.objectExists(this.props.siteVisitNote.images) || true ?
<FontAwesomeIcons style={styles.icon} name="picture-o"/> : null}
</View>
</View>
<MentionsText style={styles.text}
>{this.getText()}</MentionsText>
</View>
</TouchableHighlight>
)
}
}
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
justifyContent: "space-between",
},
headerTitle: {
flexDirection: 'row'
},
view: {
flex: 1,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#efeff4',
padding: 8,
minHeight: 40,
},
buttons: {
flexDirection: "row",
alignSelf: 'flex-end',
},
icon: {
fontSize: 20,
paddingRight: 5,
color: "#333333",
padding: 8
},
title: {
color: "#333333",
fontSize: 14,
fontWeight: 'bold',
padding: 8,
},
text: {
color: "#333333",
fontSize: 14,
padding: 8
}
});
Thanks!
Add flex: 1 to headerTitle, and title.
If that doesn't work see my working example of this layout here which you can compare.
https://gist.github.com/WilliamIPark/2ad3ecf47c5c1e559086e4b10d0cf018
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
ScrollView
} from 'react-native';
export default class App extends Component {
render() {
return (
<ScrollView
style={{ backgroundColor: '#edf2f9'}}
contentContainerStyle={styles.container}
>
<View style={styles.card}>
<View style={styles.header}>
<View style={styles.iconTitle}>
<View style={styles.icon} />
<Text>Hello world</Text>
</View>
<View style={styles.buttonWrap}>
<View style={styles.button} />
<View style={styles.button} />
<View style={styles.button} />
</View>
</View>
<View>
<Text>
Some other content...
</Text>
</View>
</View>
<View style={styles.card}>
<View style={styles.header}>
<View style={styles.iconTitle}>
<View style={styles.icon} />
<Text style={styles.title}>
Hello world this is some really long title right here, that
goes on and on and on. And then some!
</Text>
</View>
<View style={styles.buttonWrap}>
<View style={styles.button} />
<View style={styles.button} />
<View style={styles.button} />
</View>
</View>
<View>
<Text>
Some other content...
</Text>
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#edf2f9',
},
card: {
backgroundColor: 'white',
height: 200,
width: 320,
shadowColor: 'black',
shadowOpacity: 0.25,
shadowOffset: {x: 10, y: 10},
padding: 10,
marginTop: 10,
},
header: {
borderBottomWidth: 0.5,
borderBottomColor: 'lightgrey',
flexDirection: 'row',
marginBottom: 10,
justifyContent: 'space-between',
},
iconTitle:{
flexDirection: 'row',
flex: 1,
marginBottom: 10,
},
icon: {
height: 24,
width: 24,
backgroundColor: 'black',
marginRight: 5,
},
title: {
flex: 1,
},
buttonWrap: {
flexDirection: 'row',
},
button: {
height: 24,
width: 24,
backgroundColor: 'red',
marginLeft: 5,
}
});