I would like to implement a dynamic carousel view of screens (similar to Swiper). I was thinking of creating a View with conditional rendering that would display a screen by selectedId corresponding to each screen, but that would cause a re-render on every screen, unless I have a state for each one of them.
Is there any better solution to make a carousel view of screens without using navigation and keep the data on the screen saved?
I have used react-native-progress-steps for this solution. I have modified the config file a little and wrote a dummy data template for it.
Dummy data:
const reviewData = [
{
id: "1",
serviceID: 0,
},
{
id: "2",
serviceID: 1,
},
{
id: "3",
serviceID: 2,
},
];
render (disregard colors):
<View style={styles.container}>
<ProgressSteps
activeStepIconColor={defaultColors.white}
completedProgressBarColor={settings.colors.primary}
progressBarColor={defaultColors.light}
activeStepIconBorderColor={settings.colors.primary}
completedStepIconColor={settings.colors.primary}
disabledStepIconColor={defaultColors.light}
activeStepNumColor={defaultColors.dark}
disabledStepNumColor={defaultColors.mediumLight}
>
{reviewData.map((item, index) => (
<ProgressStep
nextBtnStyle={styles.nextButtonStyle}
previousBtnStyle={
index === 0
? styles.disabledButton
: styles.prevButtonStyle
}
nextBtnTextStyle={styles.nextButtonTextStyle}
previousBtnTextStyle={styles.prevButtonTextStyle}
previousBtnText={`Назад`}
nextBtnText={`Дальше`}
finishBtnText={`Завершить`}
previousBtnDisabled={index === 0 ? true : false}
>
<View style={{ alignItems: "left" }}>
<AppText>
{item.serviceID},{index}
</AppText>
</View>
</ProgressStep>
))}
</ProgressSteps>
</View>
I am satisfied with the solution, but if you have any other solutions, please let me know :)
Related
Is there a way to bold certain words of a sentence in an object array? I thought about making like tags, then bolding those tags somehow? I am using React by the way. I am not sure of the logic on when to bold them but it makes more sense to me to identify the words in my data file..The goal is to be able to render the tags i choose as bolded from the given text in my data. So welcome and audience should show bold.
//decide on the bolded words//
const tags = ["Welcome", "Audience"];
//somehow bold the words///
function formatted() {
tags.map((tag) => {
return <span style={{ fontWeight: "bold" }}>{tag}</span>;
});
}
MY DATA
const Data = [
{
index: 0,
title: "Title 1",
layout: "wide",
content: [
{
type: "paragraph",
text: "Welcome the the course.",
},
{
type: "paragraph",
text: "The purpose of this training is to provide an overview.",
},
],
image: demo,
width: imageSize,
},
{
index: 1,
title: "Title 2",
layout: "standard",
content: [
{
type: "paragraph",
text: "The target audience for this course is anyone.",
},
{
type: "paragraph",
text: "Successful completion of this course is required.",
},
],
image: demo2,
width: imageSize,
},
]
//Or maybe alternatively bold them using innerhtml???//
//PARAGRAPH
function Paragraph({ text, size }) {
const formatted = text.replace(/(the word)/g, (it) => `<b>${it}</b>`);
return <span dangerouslySetInnerHTML={{ __html: formatted }}></span>;
}
If you can edit your MyData file, one option might be using the react-markdown library. You would then be able to put **Double Astorisks** around the word you would like in bold then just do:
//your component
...
return (
<ReactMarkdown>
{stringFromDataFile}
</ReactMarkdown>
)
You also have the benefit of having other markdown options like header, links, etc...
If you don't want to use external libraries you could also do something like this and avoid dangerouslySetInnerHTML.
My Data
In your data file, surround the objects you would like to have in bold with any specific key. I will use **.
ex:
content: [
{
type: "paragraph",
text: "**Welcome** the the course.",
},
{
type: "paragraph",
text: "The purpose of this training is to provide an overview.",
},
],
now you can just do:
const data = myData.split('**');
const boldOffset = myData.startsWith('**') ? 0 : 1;
return (
<>
data.map((string, index) =>{
// if we started with bold value
if(boldOffset === 0){
return (<span style={{ fontWeight: index % 2 === 0 ? "bold" : undefined }}>{string}</span>);
}else
return (<span style={{ fontWeight: index % 2 > 0 ? "bold" : undefined }}>{string}</span>);
});
</>
)
If we split the data using the key (**) that defines bold values, we know that every other value is bold. We then just need to check if the first value is bold or not.
Not an exact answer but getting close, if anyone has a better example please post. It doesn't work yet but i maybe need to use spread operator? i will post when closer as no one has posted an example yet.
{
type: "paragraph",
tags: ["Welcome", "course"]
text: "Welcome the the course.",
},
{
type: "paragraph",
text: "The purpose of this training is to provide an overview.",
},
function Paragraph({ text, size, tags }) {
const formatted = text.replace(`${tags}`, (it) => `<strong>${it}</strong>`);
return <div dangerouslySetInnerHTML={{ __html: formatted }} style={{
fontSize: size }} />;
}
So I have typical json result from Google maps api
"html_attributions" : [],
"next_page_token" : "CqQCFgEAAL2fPrvHrkhgi11wNUC40-FEYJ93rH1Bo9FRkqxMfMlvqaEQv6hgiLoJXmeFBFMA6Uw-kcECgRXs_VzE6QVNPMRTrh402Z9Rn1dUVC_2B3WwopG_KNcftFARDQZD0K-a7swHAb_jftghftWtzrTqa8GTKMKuLCHS6ZJooPXOGpndn1h2yYO7bIF4GiPE80HgaLrgZDAJ-bf71LXhWmvmPtPiU0UGZeH1Zp4945yS5PHK1WVCMPoIR2XVqv9d9k08ZKqQPtnNOS1YsvdZOaY1Jy76eFIhCMFr1yhR0GyBmtVs6_wf9yEdi-SXSjqiciD77bk9pKf2p4b8C_9jhY3SJvB9wgLGUbDS0Y3gFG63EHcMKva4FVHFiov-7_abNk3i3RIQGSQOIFfRj3zZaSVngR8PcRoUa9z0FhpaicLUkREG-VRpE_wUZhE",
"results" : [
{
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_recreational-71.png",
"name" : "Park Leśny Zdroje",
"photos" : [
{
"height" : 3024,
"html_attributions" : [
"\u003ca href=\"https://maps.google.com/maps/contrib/103847965103971799822\"\u003eKSD\u003c/a\u003e"
],
"photo_reference" : "CmRaAAAAHvmblqXHuIBST9cZZI3yLtIuay_of90rDBUOoBQ64Luh7U_bVFTK5jhliXE9pFhRWMZjw4yHJXOFbxKQYBmEJwvBLNXkQGZrr5CvjlPT0HBHKququkGzjA8JJvbIdVC4EhCX_9SFH1F88ezn0N9XUaEfGhQpUDqAXZzLaSn0rrIIdMFwjCz6yA",
"width" : 4032
}
],
},
]
And i cannot somehow access photo_reference from array photos.
{parks.results.map((element,index)=>
<View key={index} style={AppStyle.mapCard}>
<View style={AppStyle.mapCardImg}>
//Tried this
<Text>{element.photos.map(item => item.photo_reference)}</Text>
//and this
<Text> {element.photos.photo_reference} </Text>
</View>
<View style={AppStyle.mapCardDescription}>
<Text>{element.name}</Text>
<Text>
({element.rating})
</Text>
</View>
</View>
</View>
)}
I know it's array in array and i need to iterate through it but it doesnt work.
This way: {element.photos.map(item => item.photo_reference)} i have undefined is not an object(evaluating element.photos.map)
This way {element.photos.photo_reference} undefined is not an object
Whats the solution in react Native?
Google Maps Api is not always returning every property of single Place. Error was that some places doesn't have photos so there's no array in json. The same about rating and others.
Adding conditions to check if variable exists solves problem.
element.photos && element.photos.map(item => item.photo_reference)
How to get data from SQLite database and pass this data to Picker Component with values and labels?
The question is so general, so I will answer generally. To get data from SQLite you can install this package on your react native project:
https://www.npmjs.com/package/react-native-sqlite-storage
Then you can use this pass your data in item section of this nice component:
https://www.npmjs.com/package/react-native-picker-select
Just follow the instructions for installing and configurations.
To passing the data to the picker it is enough to put your data in the state and convert to to the proper way. To convert you can use following code and put it in the place that you retire the data:
var myMatrix=[];
yourRetriveData.map(function (item, ) {
// console.log ("item [yourRetriveData.map]", item);
obj= {
"label": item.X,
"value": item.Y,
};
myMatrix.push(obj);
});
that.setState({dataForPicker: myMatrix });
Instead of X and Y you can put your proper felids. Then in the picker you need this:
{!this.state.dataForPicker ?
<ActivityIndicator size="small" color="#fff" />:<RNPickerSelect
placeholder={{
label: this.state.label,
value: this.state.value,
}}
items={this.state.data}
onValueChange={(value, index) => {
this._handleItemPicked(value, index)
}}
placeholderTextColor={"#FFF"}
placeholderTextColor={'rgba(255,255,255,1)'}
value={this.props.value}
style={{ ...pickerSelectStyles }}
hideIcon={true}
/>}
I hope I could help.
I'm new in react native and I'm having trouble with displaying all the json data in a listview with multiple arrays. I need to save the data using asyncStorage. The json data is from MQTT. Is it possible to use multiple map iterator inside return in react native?
here is my code for displaying the JSon in my listview:
<ListView
enableEmptySections={true}
dataSource{this.state.ds.cloneWithRows
(this.props.quotes)}
renderRow={this.renderRow.bind(this)}
/>
here is my render row:
renderRow(rowData) {
return (
<TouchableOpacity>
<View style={styles.row}>
<Text style={styles.description}>
{rowData.id}
</Text>
<Text style={styles.description}>
{rowData.a}
</Text>
</View>
</TouchableOpacity>
)
}
And here is my JSON Data:
{
"sample":[
{
"id": 1,
"Sam1":[
{
"a": 1,
"b": 2,
"arr": [
{
"b": 1,
"c": 2,
}
]
},
]
}
]
}
I have 3 arrays how can I display the 2nd and third array in my listview?
Thanks for answering :)
cheers,
You can just map over those sub arrays. Here's an example using your JSON. It might make more sense if you provided more realistic JSON, but here goes.
rowData.Sam1.map(sam => {
<Text>{sam.a}</Text>
sam.arr.map(a => {
<Text>{a.b}</Text>
}
}
React-native: 0.47.1
How would I maintain the aspect ratio for height when the width is 100%? Basically I want to auto scale the height while maintaining the aspect ratio. The images will be displayed in a FlatList (not necessarily, if something else worls I'm happy to change the FlatList). Images are displayed from an array of data which is set in the state:
export default class ImageTest extends Component {
constructor(props) {
super(props)
this.state = {
data : [
{id: 1, name: "image1", url: "http://urlOfImage.com/1.jpg"}
{id: 2, name: "image2", url: "http://urlOfImage.com/2.jpg"}
{id: 3, name: "image3", url: "http://urlOfImage.com/3.jpg"}
{id: 4, name: "image4", url: "http://urlOfImage.com/4.jpg"}
{id: 5, name: "image5", url: "http://urlOfImage.com/5.jpg"}
];
}
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem = {({item})=>
<Text style={styles.item}>{item.name}</Text>
<Image
source={uri: item.url}
style={styles.myImageStyle} />
}
/>
</View>
)
}
}
const styles = StyleSheet.create(
myImageStyle: {
width: Dimensions.get('window').width,
height: /* WHAT DO I PUT HERE ?? */
}
)
So the images may vary in height, original height may be 700px, some maybe 1200px, or even a square image. How would I define the height for each image since they're coming from an array?
Many thanks
You can take a dimensions of the image from URI. You can loop through your array and take the dimensions for each image using static method getSize() included in Image component. Here is a documentation for this method
Example:
const preloadedImgData = []
this.state.data.forEach((img) => {
Image.getSize(img.url, (w, h) => {
img.dimensions = {w, h}
preloadedImgData.push(img)
})
})
I'm not sure if above code is 100% correct but you got the idea :)
EDIT:
Also you can use this module which should do everything for you: react-native-fit-image
- I'm not owner of this module