How to wrap text in react native inside a ListView? - react-native

I'm trying to make simple messaging bubbles like this:
Desired outcome Image
however, I can't figure out how to make the red background wrap the text only. I keep gutting this:
Code output Image
import React, { Component } from 'react';
import { Container, Header, Content, Button, Left, Icon, Body, Title, Right } from 'native-base';
import { View, StyleSheet, TextInput, ScrollView, ListView, Text } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {text: '', dataSource: ds.cloneWithRows(['hi', 'My Name is adam']),};
}
render() {
return (
<Container style={styles.container}>
<ListView
dataSource={this.state.dataSource}
style={styles.list}
renderRow={(rowData) =>
<Text style={styles.senderMessageText}>
{rowData}
</Text>
}
/>
</Container>
);
}
}
const styles = StyleSheet.create({
container:{
backgroundColor: 'green'
},
list:{
backgroundColor:'blue'
},
senderMessageText: {
backgroundColor:'red',
padding: 8,
marginTop: 10
}
});
I have tried everything.. Please help

Try this solution:
React Native: "Auto" width for text node
It suggests to use the alignSelf property. Use alignSelf: 'flex-start'
PS: ListView is deprecated.Use FlatList instead. It has better performance for large data

Related

Problem with lining up contents: react native

I'm currently having a problem with the clickable size of a reusable button which includes an icon and text. When I run this code it seems like the entire row becomes clickable when I only want the icon and text to become clickable. Does anyone know how to solve this problem? Thanks
App.js
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import IconTextButton from './components/iconTextButton';
export default function App() {
return (
<View style={styles.container}>
<Text style={{marginTop: 100}}>My First React App! Sike </Text>
<IconTextButton iconFont="ionicons" iconName="pencil" iconSize={25} text="Add Items"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'powderblue',
},
});
iconTextButton.js
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon}>
<Text style={styles(iconSize).buttonText}>{text}</Text>
</FontIcon>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})
Along with the code I've tried, I've also tried to keep and as seperate contents whilst adding a flexDirection: 'row' inside styles.container. This keeps the contents in the same line but it still makes the whole row clickable. I've also tried putting everything in a and moving the styles.container to the component and adding a height: size into styles.container. This makes the clickable component limited however, the component is hidden underneath due to the restricted height. I have also tried simply just using instead of making a reusable const that its an input. The same thing applies.
You can wrap your Icon and Text Component in a View component and then wrap it inside a TouchableOpacity Component
Try this or do something like this :
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container}>
<View style={styles(iconSize).iconTextContainer}>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon} />
<Text style={styles(iconSize).buttonText}>{text}</Text>
</View>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
iconTextContainer: {
flexDirection: 'row',
alignItems: 'center',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})

react native make part of TextInput to be bold or italics at run time

I have a simple TextInput App like below:
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = { textValue: '' };
this.handleTextInputChange = this.handleTextInputChange.bind(this);
}
handleTextInputChange(input) {
this.setState({textValue: input})
}
render() {
return (
<KeyboardAvoidingView
behavior="padding"
style={{flex:1}}
enabled>
<TextInput
style={styles.textInputStyle}
multiline={true}
onChangeText={this.handleTextInputChange}
value={this.state.textValue}
/>
</KeyboardAvoidingView>
);
}
}
What I'd like to do is when I write ##hello in TextInput, what's instantaneously rendered in TextInput screen is hello in bold just like Markdown editing in Dropbox Paper. Similarly, when I write _hello_, what I see in the screen is hello italicized.
Screen
Can I do that? (Have part of TextInput to have different styles)
So far, it seems like TextInput can only take one style?
If we cannot have different styles TextInput, what might be an alternative to make part of (some kind of TextInput) bold, italicized, bigger, smaller...
I'm pretty sure you can nest Text within TextInput like this:
<TextInput>
<Text style={{fontWeight:'bold'}}>I'm bold</Text>
</TextInput>
Just parse the text and append Text with different styles as needed.
You can use this lib react-native-easy-markdown to render markdown text and hide the text input like this and render the markdown component instead. :
import React, { Component } from 'react';
import { StyleSheet, View, TextInput, TouchableOpacity } from 'react-native';
import Markdown from 'react-native-easy-markdown';
export default class App extends Component {
state = { text: 'type here ...' };
onClick = e => {
this.textInput.focus();
};
render() {
return (
<View style={styles.container}>
<TextInput
ref={ref => (this.textInput = ref)}
style={{ position: 'absolute', left: -1000, top: -1000 }}
onChangeText={text => this.setState({ text })}
/>
<TouchableOpacity onPress={this.onClick}>
<Markdown>{this.state.text}</Markdown>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
here is a demo of the code :

React Native code explanation

I have a simple app application project that I would appreciate if someone would explain the logic behind the code.
On the click on the button the text that is inside the text input appears on the imageBackground.
FilterView.js:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
Button, Platform, TouchableOpacity, TextInput, ImageBackground } from 'react-native';
import { captureRef } from "react-native-view-shot";
import { Input } from 'react-native-elements';
import DynamicText from './DynamicText';
export default class FilterView extends Component {
constructor(props) {
super(props);
this.state = {
text: '',
imageURI: 'https://reactnativecode.com/wp-content/uploads/2018/02/motorcycle.jpg',
}
}
captureScreenFunction = () => {
captureRef({
format: "jpg",
quality: 0.8
})
.then(
uri => this.setState({ imageURI: uri }),
error => console.error("Oops, Something Went Wrong", error)
);
}
onTextReceived = (text) => {
this.setState({text});
}
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Capture Device Screenshot" onPress={this.captureScreenFunction} />
<ImageBackground source={{uri: this.state.imageURI}} style={{
width: 200,
height: 300,
marginTop: 5,
alignItems: 'center',
justifyContent: 'center'
}}>
<Text style={{color: 'white'}}>{this.state.text}</Text>
</ImageBackground>
<View style={{ flexDirection: 'row', justifyContent: 'space-around' }}>
<View>
<DynamicText onChangeText={this.onTextReceived}/>
</View>
</View>
</View>
);
}
}
DynamicText.js:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button, Platform, TouchableOpacity, TextInput, ImageBackground } from 'react-native';
export default class DynamicText extends Component {
constructor(props) {
super(props);
this.state = {
text: '',
mode: 1 // 1 = edit, 2 = view
}
}
onChange = (text) => {
this.setState({text});
this.props.onChangeText(text);
}
render() {
return (
<View ref="dymanicView">
<TextInput
ref="newItemText"
style={{ height: 40 }}
placeholder="Type something..."
onChangeText={(text) => this.onChange(text)}
/>
</View>
)
}
}
DynamicText.defaultProps = {
onChangeText: () => {}
}
I would like to understand about the defaultProps. For instance what does it do and when can I use it. Also please explain step by step the order of defining and transferring data between the components.
First of all, stackoverflow is not a platform for this type of question. You have to understand first by yourself and then still you have any doubt then put it with code. Anyways I'll explain how it will call when you run your project.
step-1:
first of all FilterView.js is loaded then load everything which you wrote in import tag and in render function.
step-2
then this.state is mutable. This means that state can be updated in the future while props can't. we can initialize state in the constructor, and then call setState when we want to change it.
step-3
then render method call which display what you want/write.
step-4
then captureScreenFunction is a function which you have to call onPress event of Button and onTextReceived is also a function which is call on onTextChange method.
function can bind in different ways but here captureScreenFunction is bind like this captureScreenFunction = () => {} or you can bind like this this.captureScreenFunction = this.captureScreenFunction.bind(this);
step-4
DynamicText.js file get data using this.props which is write in this file. In this file onChange = (text) => {} which calls onChangeText() function which is wrote inside FilterView.js using this.props.
and at last for default.props I'm giving you a link please refer this.
defaultProps in React Native?
Hope it will help you.

Displaying Images and text in ListView for React Native

I am trying to load images via a url and text using ListView and show data into List but when I populate it in a listview Image and text then my images are not show.
My code is:
import React, { Component } from "react";
import { ListView, Text, View, Image, StyleSheet } from "react-native";
const styles = Style.create({
container: {
flex: 1,
marginTop: 20
}
});
class ListViewDemo extends React.Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
dataSource: ds.cloneWithRows(["row 1", "row 2"])
};
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={data => {
<View style={styles.container}>
<Image
source={{
uri:
"https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg"
}}
style={{ width: 193, height: 110 }}
/>
<Text> Asad </Text>
</View>;
}}
/>
);
}
} [enter image description here][1]
export default ListViewDemo;
Problem
The images would not render in your list view.
Solution
I have noticed sometimes having trouble getting images to show up when components render in react. Especially when they are loaded over a network call. I added a style to your image component, placed the image source into a variable and fixed some syntax errors you had in your code.
The biggest problem, and the reason it was not rendering the image was you added {} around your renderRow prop which would call for the need of a return statement. When you supply () around the return data, return is implied because your using a fat arrow function.
So this,
renderRow = { (data) => { }}
Became this,
renderRow={data => ( )}
Example
You can copy and paste this whole component into you code and it will work.
This has been tested,
import React, { Component } from 'react'; import { ListView, Text, View, Image, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
},
img: {
width: 193,
height: 110,
},
});
class ListViewDemo extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
};
}
render() {
const imageSource = 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg';
return (
<ListView
dataSource={this.state.dataSource}
renderRow={data => (
<View style={styles.container}>
<Image
source={{ uri: imageSource }}
style={styles.img}
/>
<Text>{data}</Text>
</View>)}
/>
);
}
}
export default ListViewDemo;
Proof of Concept
Please see the image showing your component working now,
React Native provides a suite of components for presenting lists of data. Generally, you'll want to use either FlatList or SectionList first and then provide the image in the data source.
import React from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
img: {
width: 100,
height: 100
},
});
const FlatListBasics = () => {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Devin', image: 'image1.png'},
{key: 'Dan', image:'image2.png'},
]}
renderItem={({item}) => <Image source={item.image} style={styles.img} /><Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
export default FlatListBasics;
reference: https://reactnative.dev/docs/using-a-listview

TextInput in react native iOS

I have a TextInput component in react native
<TextInput
style={styles.searchBar}
value={this.state.searchText}
onChange={this.setSearchText.bind(this)}
placeholder='Search State'
/>
This is working perfectly fine in android, but Textbox is not showing in iOS app. And, there is no what to find what the issue is.
Can anybody help with this issue ?
Here is a code sample that demonstrates the need to provide a height for the TextInput component on iOS. It's not explicitly stated in the docs but reviewing it closely you'll notice the iOS section of the code samples provides a height while the android samples do not. Here is a complete code sample that displays a TextInput in the center of the view:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
TextInput,
View
} from 'react-native';
class MyApp extends Component {
constructor (props) {
super(props);
this.state = {
searchText: ''
};
}
setSearchText (e) {
this.setState({
searchText: e.target.value
});
}
render () {
return (
<View style={styles.container}>
<TextInput
style={styles.searchBar}
value={this.state.searchText}
onChange={this.setSearchText.bind(this)}
placeholder='Search State'
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
searchBar: {
borderWidth: 1,
height: 40
}
});
AppRegistry.registerComponent('MyApp', () => MyApp);
If this doesn't help as a sanity check in debugging your code, please post the style definition (styles.searchBar) you have configured for your TextInput so we can give that a better test.
you should give the textinput height and width to display the textinput as:
<Textinput style={{height:200, width:300}}/>