I'm looking for someone that could help me just images in a flatlist grid.
I was able to get it working with text but not images in the assets folder.
I want to have separate images that will be stored in the assets folder to be in the boxes of the flatlist grid.
Please let me know if you need more information!
Here is the code:
import React from 'react';
import { View, Image, Text, StyleSheet, TouchableOpacity, FlatList, Dimensions } from 'react-native';
import { drawer } from '../navigation/AppNavigation';
import { hp, wp } from '../utils/responsiveScreen';
const dataList = [{ key: '1' }, { key: '2' }, { key: '3' }, { key: '4' }, { key: '5' },{ key: '6' },{ key: '6' },{ key: '6' }]
const numColums = 2
const WIDTH = Dimensions.get('window').width
const Main = () => {
formatData = (data, numColums) =>{
const totalRows = Math.floor(data.length / numColums)
let totalLastRow = dataList.length - (totalRows * numColums)
while(totalLastRow !== 0 && totalLastRow !== numColums){
dataList.push({'key': 'blank', empty: true})
totalLastRow++
}
return dataList
}
_renderItem = ({ item, index }) => {
let {itemStyle, itemText} = styles
if(item.empty){
return <View style={[itemStyle]}/>
}
return (
<View style={itemStyle}>
<Text style={styles.itemText}>{item.key}</Text>
</View>
)
}
return (
<View style={styles.container}>
<TouchableOpacity
style={{ height: 50 }}
onPress={() => drawer.current.open()}>
<Image source={require('../assets/menu.png')} />
</TouchableOpacity>
<Text style={styles.textStyle}>Stars</Text>
<FlatList
data={this.formatData(dataList, numColums)}
renderItem={this._renderItem}
keyExtractor={(item, index) => index.toString()}
numColumns = {numColums}
/>
</View>
);
};
And here is the Style sheet:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
paddingTop: hp(7),
paddingHorizontal: wp(6),
},
textStyle: {
marginBottom: 20,
fontWeight: 'bold',
fontSize: 24,
color: 'black',
},
image: {
alignSelf: 'center',
height: hp(40),
width: hp(40),
marginTop: hp(3),
},
itemStyle: {
backgroundColor: 'pink',
alignItems: 'center',
justifyContent: 'center',
height: 150,
flex: 1,
margin:1,
width: WIDTH / numColums
},
itemText: {
fontSize: 50
}
});
I have attached an image of what it looks like now:
Here
UPDATE
I have updated the datalist to this:
const dataList = [{ key: '1',image: required('../assets/backGround.png')}, { key: '2',image: required('../assets/backGround.png') }, { key: '3' ,image: required('../assets/backGround.png')}]
And the view to this:
<View style={itemStyle}>
{/* <Text style={styles.itemText}>{item.key}</Text> */}
<Image
style={styles.image}
source={item.image}
/>
</View>
and I now get the error:
TypeError: (0, _reactNative.required) is not a function. (In '(0, _reactNative.required)('../assets/backGround.png')', '(0, _reactNative.required)' is undefined)
const dataList = [{ key: '1',image: required('../assets/backGround.png')}, { key: '2',image: required('../assets/backGround.png') }, { key: '3' ,image: required('../assets/backGround.png')}]
needs to be
const dataList = [{ key: '1',image: require('../assets/backGround.png')}, { key: '2',image: require('../assets/backGround.png') }, { key: '3' ,image: require('../assets/backGround.png')}]
you need to add require() to the source in the image tag
Related
In React-Native, how do I set borderRadius to Text-components?
I've tried using borderRadius in text stylesheet but it not work:
import { formatPhone, mapNameWithLocalContact } from '#chat/common/Utils/ChatUtils';
import ChatFunctions from '#chat/service/ChatFunctions';
import { Colors, Text } from '#momo-platform/component-kits';
import React from 'react';
import { StyleSheet, View, TextStyle } from 'react-native';
import { parseValue } from 'react-native-controlled-mentions';
import { MessageText } from 'react-native-gifted-chat';
// #ts-ignore
import ParsedText from 'react-native-parsed-text';
import { partTypes } from '../menstions';
const textStyle = {
fontSize: 16,
lineHeight: 20,
marginTop: 5,
marginBottom: 5,
marginLeft: 10,
marginRight: 10,
};
const styles = {
left: StyleSheet.create({
container: {},
text: {
color: 'black',
...textStyle,
},
link: {
color: 'black',
textDecorationLine: 'underline',
},
textMention: {
color: Colors.pink_05_b,
fontWeight: 'bold',
},
mentionMe: isMe =>
isMe
? {
color: Colors.white,
backgroundColor: Colors.pink_05_b,
}
: {},
}),
right: StyleSheet.create({
container: {},
text: {
color: 'white',
...textStyle,
},
link: {
color: 'white',
textDecorationLine: 'underline',
},
textMention: {
color: 'white',
fontWeight: 'bold',
},
mentionMe: () => ({}),
}),
};
export default class MessageTextCustom extends MessageText {
constructor() {
super(...arguments);
}
render() {
const linkStyle = [
styles[this.props.position].link,
this.props.linkStyle && this.props.linkStyle[this.props.position],
];
const { parts } = parseValue(this.props.currentMessage.text, partTypes);
return (
<View
style={[
styles[this.props.position].container,
this.props.containerStyle && this.props.containerStyle[this.props.position],
]}
>
<ParsedText
style={[
styles[this.props.position].text,
this.props.textStyle && this.props.textStyle[this.props.position],
this.props.customTextStyle,
]}
parse={[
...this.props.parsePatterns(linkStyle),
{ type: 'url', style: linkStyle, onPress: this.onUrlPress },
{ type: 'phone', style: linkStyle, onPress: this.onPhonePress },
{ type: 'email', style: linkStyle, onPress: this.onEmailPress },
]}
childrenProps={{ ...this.props.textProps }}
>
{this.props.isGroup ? (
<Text>
{parts.map(({ text, partType, data }, index) =>
partType ? (
<Text
key={`${index}-${data?.trigger ?? 'pattern'}`}
style={[
styles[this.props.position].textMention,
styles[this.props.position].mentionMe(
formatPhone(data.id) === ChatFunctions.phoneNumber
),
]}
onPress={() =>
this.props.onPressMenstion &&
this.props.onPressMenstion(data.id)
}
>
{`${data?.trigger}${mapNameWithLocalContact({
phone: data?.id,
name: data?.name,
})}`}
</Text>
) : (
<Text
key={index}
style={[
styles[this.props.position].text,
this.props.textStyle &&
this.props.textStyle[this.props.position],
this.props.customTextStyle,
]}
>
{text}
</Text>
)
)}
</Text>
) : (
this.props.currentMessage.text
)}
</ParsedText>
</View>
);
}
}
My expected style
I cannot use view to wrap this text because my text component is wrap by other text component
I've worked on it on snack you can check out this link and make sure you wrap those text with a View and use
flexDirection: 'row';
alignItems: 'center';
So to stop the View from filling the screen 100% add
alignSelf: 'start';
Checkout this link to see the code I've written for this
https://snack.expo.dev/#rajibola/spontaneous-beef-jerky
For TextStyle, borderTopRightRadius, borderTopLeftRadius, borderBottomRightRadius, borderBottomLeftRadius don't work. Only borderRadius works.
Maybe it's a bug!
import React, { Component } from "react";
import { StyleSheet, FlatList, View, Image, Text } from "react-native";
const n1 = require("../img/n1.png");
const n2 = require("../img/n2.png");
const n3 = require("../img/n3.png");
const n4 = require("../img/n4.png");
const n5 = require("../img/n5.png");
const n0 = require("../img/n0.png");
class Example extends Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 1, image: n1, title: " n1 " },
{ id: 2, image: n2, title: " n2 " },
{ id: 3, image: n3, title: " n3" },
{ id: 4, image: n4, title: " n4 " },
{ id: 5, image: n5, title: " n5" },
],
};
}
render() {
return (
<FlatList
style={styles.container}
data={this.state.data}
keyExtractor={(item) => {
return item.id;
}}
renderItem={({ item }) => {
return (
<View style={styles.box}>
<View style={styles.info}>
<Text style={styles.name}>{item.title} </Text>
<Image style={styles.image} source={{ uri: item.image }} />
</View>
</View>
);
}}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 30,
},
info: {
flex: 1,
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
},
image: {
width: 173,
height: 88,
},
title: {
color: "#707070",
opacity: 1,
},
box: {
marginLeft: -120,
marginTop: 10,
backgroundColor: "white",
flexDirection: "row",
marginBottom: 20,
},
});
This is part of the code that I have deleted some code not relevant to this question.
My question is how do I change all images(n1-n5) by one click to n0.
The page will show 5 different images(n1-n5) in a list, then after clicking a button, all images will be replaced by n0.
I got some idea about setState, but I am new to React and don't know how to make it work(or not state) even after search.
BTW, its a webpage, but I use react-native-web to get the images more pretty arranged.
This is a simple map operation.
handleClick = () =>
this.setState((prev) => ({
data: prev.data.map((item) => ({
...item,
image: n0,
title: "n0",
})),
}));
Start by adding extraData to the flat list to re render when button clicked
<FlatList
style={styles.container}
data={this.state.data}
extraData={this.state}
keyExtractor={(item) => {
return item.id;
}}
renderItem={({ item }) => {
return (
<View style={styles.box}>
<View style={styles.info}>
<Text style={styles.name}>{item.title} </Text>
<Image style={styles.image} source={{ uri: item.image }} />
</View>
</View>
);
}}
/>
....
//add function for button click:
onButtonClicked(){
//create the new data array
//replace it with the old array state
this.setState({data: new_data}); //flat list should re render when state changed
}
I want to have 4 boxes, each box with a different color, and I want to do that loading each style from map(). The below code doesn't compile, I wrote it so you understand what I'm trying to do. The error derives from inside the View at styles.{box.name}, I want instead of {box.name} to put array's elements so the function can take Stylesheet's props.
export default function Imagesfun() {
const array = [{
name: "box1",
},
{
name: "box2",
},
{
name: "box3",
},
{
name: "box4",
},
{
name: "box5",
}]
return (
<View style={styles.container}>
{array.map(box => <Text style={styles.{box.name}} key={box.name}>{box.name}</Text>)}
</View >
)
}
const styles = StyleSheet.create({
container: {
justifyContent: "space-around",
alignContent: "center",
backgroundColor: 'black',
},
box1: {
backgroundColor: 'lightblue',
},
box2: {
backgroundColor: 'lightred',
},
box3: {
backgroundColor: 'lightyellow',
},
box4: {
backgroundColor: 'lightpurple',
},
box5: {
backgroundColor: 'lightgreen',
},
});
Change {styles.{box.name}} to {styles[box.name]}. Check this Q & A for more details.
Try as following:
<View style={styles.container}>
{array.map(box => <Text style={styles.[box.name]} key={box.name}>{box.name}</Text>)}
</View >
I have a FlatList with two items. I need to append this list with another elements. When the user clicks on the button, the data from the text inputs should appear in the end of the FlatList. So, I've tried to push data object to the end of the list's array, but new item replaces the last one.
import React, { useState } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
export default function HomeScreen() {
var initialElements = [
{ id : "0", text : "Object 1"},
{ id : "1", text : "Object 2"},
]
const [exampleState, setExampleState] = useState(initialElements);
const [idx, incr] = useState(2);
const addElement = () => {
var newArray = [...initialElements , {id : toString(idx), text: "Object " + (idx+1) }];
initialElements.push({id : toString(idx), text: "Object " + (idx+1) });
incr(idx + 1);
setExampleState(newArray);
}
return (
<View style={styles.container}>
<FlatList
keyExtractor = {item => item.id}
data={exampleState}
renderItem = {item => (<Text>{item.item.text}</Text>)} />
<Button
title="Add element"
onPress={addElement} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
},
});
import React, { useState } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
export default function HomeScreen() {
var initialElements = [
{ id : "0", text : "Object 1"},
{ id : "1", text : "Object 2"},
]
const [exampleState, setExampleState] = useState(initialElements)
const addElement = () => {
var newArray = [...initialElements , {id : "2", text: "Object 3"}];
setExampleState(newArray);
}
return (
<View style={styles.container}>
<FlatList
keyExtractor = {item => item.id}
data={exampleState}
renderItem = {item => (<Text>{item.item.text}</Text>)} />
<Button
title="Add element"
onPress={addElement} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
},
});
You are just changing the listElements array. This will NOT trigger the re rendering of the component and hence the flat list will be unchanged.
Create a state variable in the component and store your data in that so that any modification results in re rendering.
I fixed the problem of replacing elements by changing array into a state variable.
import React, { useState } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
export default function HomeScreen() {
const [initialElements, changeEl] = useState([
{ id : "0", text : "Object 1"},
{ id : "1", text : "Object 2"},
]);
const [exampleState, setExampleState] = useState(initialElements);
const [idx, incr] = useState(2);
const addElement = () => {
var newArray = [...initialElements , {id : idx, text: "Object " + (idx+1) }];
incr(idx + 1);
console.log(initialElements.length);
setExampleState(newArray);
changeEl(newArray);
}
return (
<View style={styles.container}>
<FlatList
keyExtractor = {item => item.id}
data={exampleState}
renderItem = {item => (<Text>{item.item.text}</Text>)} />
<Button
title="Add element"
onPress={addElement} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
},
});
i fixed it by defining the array outside the export function
import React, { useState } from 'react'
import { StyleSheet, View, TextInput, TouchableOpacity, Text, FlatList } from 'react-native'
let tipArray = [
{key: '1', tip: 20},
{key: '2', tip: 12}
]
const screen = function tipInputScreen( {navigation} ) {
const [ tip, setTip ] = useState('')
const addTip = ()=>{
if(tip == "")return
tipArray.push({key: (tipArray.length + 1).toString(), tip})
setTip('')
}
const logInput = (input)=>{
setTip(input)
}
const renderTip = ({ item }) => {
return(
<TouchableOpacity style={styles.listItem}>
<Text style={styles.buttonText}>{`${item.tip} $`}</Text>
</TouchableOpacity>)
}
return (
<View
style={styles.background}>
<TextInput
style={styles.input}
keyboardType={'number-pad'}
keyboardAppearance={'dark'}
onChangeText={logInput}
value={tip}
/>
<TouchableOpacity
style={styles.redButton}
onPress={addTip}>
<Text style={styles.buttonText}>Add Tip</Text>
</TouchableOpacity>
<FlatList
data={tipArray}
renderItem={renderTip}
style={styles.flatList}
/>
</View>
)
}
const styles = StyleSheet.create({
background: {
backgroundColor: 'grey',
paddingTop: Platform.OS === "android" ? 25:0,
width: '100%',
height: '100%',
alignItems: 'center'
},
input: {
marginTop:40,
color:'white',
fontSize:30,
backgroundColor: "#2e2a2a",
height: 50,
width: '90%',
textDecorationColor: "white",
borderColor: 'black',
borderWidth: 2
},
flatList:{
width: "100%"
},
listItem: {
width: "90%",
height: 50,
backgroundColor: "#2e2e2e",
borderRadius: 25,
marginVertical: 4,
marginHorizontal: "5%",
justifyContent: "center"
},
listItemTitle: {
color: "white",
textAlign: "center",
fontSize: 18
},
redButton: {
justifyContent: "center",
width: "90%",
height: 50,
backgroundColor: "red",
borderRadius: 25,
marginHorizontal: 20,
marginVertical: 10
},
buttonText: {
color: "white",
textAlign: "center",
fontSize: 18
}
})
export default screen;
this was part of an larger app, but it should do the trick, I hope it helps
Not sure where I go about declaring the array with which I want to search from, any assistance would be appreciated. I believe my issue is that I am declaring the "services' array in the incorrect area but I am not sure where else to put it! Or if the commas are the right character to be using in between strings/services
import React, { useState, Component } from 'react';
import { StyleSheet, StatusBar, View, Text, Button, TouchableOpacity } from 'react-native';
import AutoComplete from 'react-native-autocomplete-input';
class CareProviderSequenceScreen extends Component {
constructor (props) {
super (props);
this.state = {
services: [],
query: '',
}
}
render() {
const query = this.state;
const services = {
"Pick up my Prescription",
'Pick up groceries',
'Pick up dry cleaning',
'Pick up my pet',
}
return (
<View style={styles.container}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
//data to show in suggestion
data={services.length === 1 && comp(query, services[0].title) ? [] : services}
//default value if you want to set something in input
defaultValue={query}
/*onchange of the text changing the state of the query which will trigger
the findFilm method to show the suggestions*/
onChangeText={text => this.setState({ query: text })}
placeholder="Enter your need"
renderItem={({ item }) => (
//you can change the view you want to show in suggestion from here
<TouchableOpacity onPress={() => this.setState({ query: item.title })}>
<Text style={styles.itemText}>
{item.title} ({item.release_date})
</Text>
</TouchableOpacity>
)}
/>
<View style={styles.descriptionContainer}>
{services.length > 0 ? (
<Text style={styles.infoText}>{this.state.query}</Text>
) : (
<Text style={styles.infoText}>Enter The Film Title</Text>
)}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
});
export default CareProviderSequenceScreen ;
CareProviderSequenceScreen .navigationOptions = () => ({
title: "Home & Personal Care",
headerTintColor: '#9EBBD7',
headerStyle: {
height: 65,
backgroundColor: '#1E5797',
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.20,
shadowRadius: 1.41,
elevation: 2,}
});
First, you are assigning an object to services array.
Second, you are not accessing the query state properly. It should be
const { query } = this.state