I am new to react native. And I would like to create dynamic color of my application on the basis of selection.
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
Image,
NavigatorIOS,
AlertIOS,
ListView,
ScrollView,
TouchableHighlight,
View
} from 'react-native';
import {
times,
uniqueId
} from 'lodash';
var Accordion = require('react-native-accordion/src/index.js');
var my = '#eee';
class AwesomeProject extends Component {
render() {
return (
<View style = {styles.group} >
<NavigatorIOS style = {styles.group}
initialRoute = {{
component: AccordionList,
title: 'Color Selector',
rightButtonIcon: require('./img/a.png'),
onRightButtonPress: () => {
AlertIOS.alert(
'Select Color',
null, [{
text: 'Red',
onPress: () =>setColor( 'red'),
}, {
text: 'Blue',
onPress: () => setColor( 'blue'),
}]
);
}
}
}
barTintColor = "#0391D7"
titleTextColor = "#fff"
tintColor = '#fff' />
<View style = {styles.line}/>
</View>
);
}
}
setColor = function(color){
if(color == 'blue')
my = '#eee';
else
my = '#aaa';
}
const AccordionList = React.createClass({
getInitialState() {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
return {
dataSource: ds.cloneWithRows(times(6, uniqueId.bind(null, 'ball_'))),
};
},
render() {
return (
<View style = {{flex: 1}} >
<ListView dataSource = {this.state.dataSource}
renderRow = {this._renderRow}
/>
</View>
);
},
_renderHeader() {
return ( <View style = { styles.listView } >
<Image style = {styles.icon}
source = {require('./img/1.jpg')}/>
<Text> Click to Expand {my}< /Text>
</View>
);
},
_renderContent() {
return ( <View style = {styles.container} >
<Text style = {styles.welcome} >
{
'greeting'
}
Welcome to React Native!
</Text>
<Text style = {
styles.instructions
} >
To get started, edit index.ios.js
</Text>
<Text style = {
styles.instructions
} >
Press Cmd + R to reload, {
'\n'
}
Cmd + D or shake
for dev menu
</Text>
</View>
);
},
_renderRow(rowData) {
return ( <Accordion header = {
this._renderHeader()
}
content = {
this._renderContent()
}
duration = {
300
}
easing = "easeOutCubic" />
);
}
});
const styles = StyleSheet.create({
icon: {
height: 20,
width: 20,
alignItems: 'flex-end',
borderWidth: 1
},
listView: {
alignItems: 'flex-end',
paddingTop: 15,
paddingRight: 15,
paddingLeft: 15,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: my,
backgroundColor: my,
},
line: {
backgroundColor: '#bbbbbb',
height: StyleSheet.hairlineWidth,
},
container: {
flex: 1,
borderWidth: 1,
justifyContent: 'center',
alignItems: 'flex-end',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#3333f3',
marginBottom: 5,
},
group: {
backgroundColor: 'white',
flex: 1
},
groupSpace: {
height: 15,
padding: 10
},
});
const styles_a = StyleSheet.create({
icon: {
height: 30,
width: 30
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
line: {
backgroundColor: '#bbbbbb',
height: StyleSheet.hairlineWidth,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#3333f3',
marginBottom: 5,
},
listView: {
alignItems: 'flex-start',
paddingTop: 15,
paddingRight: 15,
paddingLeft: 15,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: my,
backgroundColor: '#fafafa',
},
group: {
backgroundColor: 'white',
flex: 1,
padding: 10
},
groupSpace: {
height: 15,
padding: 10
},
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
Whenever I select a new color and alert it, it shows me the color selection but, doesn't update the background color of my list.
Any idea what I am doing wrong.
Try this:
Instead of storing the color in a global variable, you should store it in the component's state. If you don't know what state means in React, consider reading this article.
I see you call a setColor function to change the variable my. Instead you could call
this.setState({currentColor: 'red'})
and then in a render() method, you could append it to an array to overwrite the default style:
<SomeComponent style={[styles.myStyle, {backgroundColor: this.state.currentColor}]}/>
The point of doing this is that setState triggers a new UI rendering.
Related
I have an array of items which I have retrieved from an Object. The array has 5 items. It looks like this:
I have saved the array in my state as :
this.state={
serviceDetails: planDetails[0].nbs_plans.map(service => service.extension_attributes.productServicetList.map(name=>name.name)),
}
Now, I am trying to render the array in my component using map function like :
{
this.state.serviceDetails.map((serviceName) => {
return (
<SelectableChips initialChips={serviceName} />
);
})
}
But the problem is all the arrays are coming together at the same place as shown below:
The way it should be is : The first "See more" should be at the first section, the 2nd at the 2nd and so on.
My complete code for this component looks like this:
//This is an example code for FlatList//
import React from 'react';
import {
StyleSheet, FlatList, Text, View, Alert , Image, TouchableOpacity
} from 'react-native';
import SelectableChips from '../../../components/Chip/SelectableChips';
import CheckBox from '../../../components/CheckBox';
import propTypes from 'prop-types';
import Service from './Service';
import { planDetails } from '../../../api/mockedData/PlanServiceDetails';
class Selected_Items_Array {
constructor() {
selectedItemsArray = [];
this.state = {
planName: planDetails[0].nbs_plans.map(data => data.name),
serviceDetails: planDetails[0].nbs_services.map(data => data.service_line),
};
var result = planDetails.filter(d => {
return d.nbs_plans[0].name = "TruCompleteā Lawn Care Plan";
});
// alert(Object.keys(planDetails).length);
// alert(Object.keys(planDetails[0].nbs_plans).length);
// alert(JSON.stringify(planDetails[0].nbs_plans[0].productId));
// alert(JSON.stringify(planDetails[0].nbs_plans[0].name));
// alert(JSON.stringify(planDetails[0].nbs_plans.map(data => data.name)));
}
pushItem(option) {
selectedItemsArray.push(option);
}
getArray() {
return selectedItemsArray;
}
}
export default class Services extends React.Component {
constructor(props) {
super(props);
this.state = {
// FlatListItems: [
// { id: '1', value: 'TruGreen Mosquito Defense' ,applicationType:'annual' },
// { id: '2', value: 'Sprinkler Maintenance Program' ,applicationType:'first' },
// { id: '3', value: 'Soil Treatment to balance the PH of the lawn-' ,applicationType:'priceper'},
// { id: '4', value: 'Tree & Shrub Care' ,applicationType:'customquote'},
// ],
planName: planDetails[0].nbs_plans.map(data=>data.name),
serviceDetails: planDetails[0].nbs_plans.map(service => service.extension_attributes.productServicetList.map(name=>name.name)),
};
selectedArrayOBJ = new Selected_Items_Array();
alert(JSON.stringify(planDetails[0].nbs_plans.map(data => data.name)));
alert(JSON.stringify(planDetails[0].nbs_plans[0].extension_attributes.productServicetList.map(data=> data.name)));
alert(JSON.stringify(planDetails[0].nbs_plans.map(service => service.extension_attributes.productServicetList.map(name=>name.name))));
alert(this.state.planName);
alert(this.state.serviceDetails);
}
FlatListItemSeparator = () => {
return (
//Item Separator
<View
style={{ height: 7, width: '100%', backgroundColor: 'transparent' }}
/>
);
};
GetItem(item) {
//Function for click on an item
Alert.alert(item);
}
render() {
return (
<View style={styles.MainContainer}>
<FlatList
data={this.state.planName}
//data defined in constructor
ItemSeparatorComponent={this.FlatListItemSeparator}
//Item Separator View
renderItem={({ item }) => (
// Single Comes here which will be repeatative for the FlatListItems
<View style={styles.cellContainerStyle} >
<View backgroundColor = {"transparent"} flexDirection = {'row'} justifyContent= {'flex-start'} margin={0}>
<View backgroundColor={'#73c573'} justifyContent= {'center'} alignItems={'center'} width={35} height={35} marginTop={0} paddingTop={0}>
<View backgroundColor={'#73c573'} width={25} height={25}>
<CheckBox size={25}
keyValue={1}
selectedArrayObject={selectedArrayOBJ}
checked={false}
label = ''
color="transparent"
labelColor="#00703c"
checkBoxClick={this.checkBoxOnClicked}/>
</View>
</View>
<View flex={1.75} backgroundColor={'transparent'} marginLeft={5}>
<Text style={{ color: '#00703c', fontSize: 21, fontFamily: 'SourceSansPro-Bold' }}> {item}</Text>
</View>
<View flex={0.15} marginTop={10}>
<TouchableOpacity style = {{ backgroundColor: 'transparent' }} onPress = {this.props.seeMore} >
<Image source={require('../../../assets/img/iOS/chevron_right.png')} style={styles.rightArrowImageStyle}/>
</TouchableOpacity>
</View>
</View>
<View style={styles.cellSubViewTwo}>
<Text style = {styles.textHeaderStyle}>This plan includes:</Text>
<View backgroundColor = {"transparent"} flexDirection='column' marginTop={5}>
{
this.state.serviceDetails.map((serviceName) => {
return (
<SelectableChips selectedChipStyle={selectableStyles} initialChips={serviceName} onChangeChips={(chips) => console.log(chips)} alertRequired={false} backgroundColor={"transparent"}
subView={
<TouchableOpacity style = {{ backgroundColor: 'transparent' }} onPress = {this.props.seeMore} >
<View backgroundColor={'transparent'} flexDirection = {'row'} alignItems= {'center'} marginLeft={5}>
<Text style={styles.seeMoreStyle}>See more</Text>
<Image source={require('../../../assets/img/iOS/chevron_right.png')} style={styles.rightArrowSeeMoreImageStyle}/>
</View>
</TouchableOpacity>
}/>
);
})
}
</View>
</View>
<Service serviceType={item.applicationType} isButton={false}/>
</View>
)}
/>
</View>
);
}
checkBoxOnClicked() {
if (selectedArrayOBJ.getArray().length == 0) {
//Alert.alert('CheckBox UnChecked');
} else {
// Alert.alert('CheckBox Checked');
}
}
}
Services.propTypes = { seeMore: propTypes.string.isRequired };
const styles = StyleSheet.create({
MainContainer: {
justifyContent: 'center',
margin: 7,
backgroundColor: 'transparent',
},
cellContainerStyle: {
padding: 0,
fontSize: 18,
flexDirection: 'column',
backgroundColor: '#ffffff',
borderColor: 'lightgray',
borderWidth: 0.5,
},
cellSubViewOne: {
flexDirection: 'row',
},
cellSubViewTwo: {
flexDirection: 'column',
marginLeft: 15,
backgroundColor: "#ffffff",
marginTop: 15,
},
cellSubViewThree: {
flexDirection: 'column',
marginLeft: 0,
backgroundColor: "#eff5ef",
marginTop: 15,
},
textHeaderStyle: {
color: '#73c573',
fontSize: 10.5,
fontFamily: "SourceSansPro-SemiBold",
},
rightArrowImageStyle: {
height: 12,
width: 12,
resizeMode: 'center',
alignItems: 'center',
tintColor: '#a6a6a6',
},
rightArrowSeeMoreImageStyle: {
height: 8,
width: 8,
resizeMode: 'center',
alignItems: 'center',
tintColor: '#ff9933',
},
seeMoreStyle: {
fontSize: 11,
color: '#ff9933',
fontFamily: "SourceSansPro-SemiBold",
},
});
const selectableStyles = StyleSheet.create({
chip: {
backgroundColor: '#73c573',
borderColor: '#73c573',
borderWidth: 1,
margin: 3,
padding: 0,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
valueStyle: {
color: '#ffffff',
fontSize: 12,
fontFamily: "SourceSansPro-Regular",
},
chipSelected: {
backgroundColor: '#73c573',
borderColor: '#73c573',
borderWidth: 1,
margin: 3,
padding: 0,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
valueStyleSelected: {
color: '#ffffff',
fontSize: 12,
fontFamily: "SourceSansPro-Regular",
},
});
Can someone please guide me how to proceed.
As each plan has as productServicetList, create a object serviceDetails where the key is the planName and the value is productServicetList.
this.state={
serviceDetails: planDetails[0].nbs_plans.reduce(
(acc, service) => ({
...acc,
[service.name]: service.extension_attributes.productServicetList.map(
name => name.name
)
}),
{}
);
}
Then render the serviceDetail as follows
{
this.state.serviceDetails[item].map(serviceName => {
return <SelectableChips initialChips={serviceName} />;
});
}
I have created a simple program to display information from my website on the app. It works on iOS but on my Android device an error shows up :
posts.map is not a function. This is my code:
import React, { Component } from 'react';
import {
View,
Text,
ActivityIndicator,
ScrollView,
StyleSheet,
Image,
Header,
} from 'react-native';
let lw = 100;
import Img from 'react-image';
let li = 'https://www.teanewsnetwork.com/profileicons/';
let bean = 'azure.jpg';
export default class App extends Component {
state = {
loading: true,
error: false,
posts: [],
};
componentWillMount = async () => {
try {
const response = await fetch(
'https://www.teanewsnetwork.com/api/fetcharticles.php?code=#NIL7*GKD60JTRTEFZ0CkvpHMJJW^-9q&starting=0&limit=40'
);
const posts = await response.json();
this.setState({ loading: false, posts });
} catch (e) {
this.setState({ loading: false, error: true });
}
};
renderPost = ({ id, title, content, authorimage, authorname }, i) => {
let b = { authorname };
return (
<View style={styles.postContent}>
<View
style={{
flex: 1,
flexDirection: 'column',
textAlign: 'center',
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={styles.postauthor}>{title} </Text>
<Image
source={{
uri: `https://teanewsnetwork.com/profileicons/${authorimage}`,
}}
defaultSource={require('./contact-outline.png')}
style={{
width: lw,
height: lw,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
borderRadius: lw / 2,
}}
/>
<Text style={styles.postauthor}>{authorname}</Text>
</View>
<Text style={styles.postBody}>{content}</Text>
</View>
);
};
render() {
const {posts, loading, error} = this.state
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator animating={true} />
</View>
)
}
if (error) {
return (
<View style={styles.center}>
<Text>
Failed to load posts!
</Text>
</View>
)
}
return (
<ScrollView style={styles.container}>
{posts.map(this.renderPost)}
</ScrollView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
borderBottomWidth: 0,
borderBottomColor: 'red',
top: 100,
zIndex: 6,
},
postauthor: {
flex: 1,
borderBottomWidth: 0,
borderBottomColor: 'red',
paddingVertical: 25,
fontSize: 18,
paddingRight: 15,
left: 10,
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center',
},
postContent: {
flex: 1,
borderBottomWidth: 20,
borderBottomColor: '#EEE',
borderRadius: 4,
fontSize: 18,
left: 0,
paddingRight: 15,
justifyContent: 'center',
alignItems: 'center',
textAlignVertical: 'center',
textAlign: 'center',
},
postBody: {
marginTop: 1,
fontSize: 18,
color: 'black',
left: 10,
textAlign: 'center',
},
center: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
I am a beginner coder on react native and would like to have some help here. The code works on iOS emulator with EXPO but doesnt work on my Android Device.
Thanks in Advance!
Most likely posts is not a array, check the type of posts.
I am using react-native-simple-picker in my app which works fine in my project if I use the default show button but I would like to show the picker when I use a different button in my project. It looks like this.refs.picker.show() in ProposalPicker.js is the function that needs to be called, but I am not sure how to access this from another component file. Currently my code results in the following error - `Cannot read property 'show' of undefined. Appreciate any help.
ProposalPicker.js
import React, { Component } from 'react';
import { Picker, View, Text } from 'react-native';
import Button from './Button';
import SimplePicker from 'react-native-simple-picker';
const options = ['Option1', 'Option2', 'Option3'];
// Labels is optional
const labels = ['Banana', 'Apple', 'Pear'];
class ProposalPicker extends Component {
constructor(props) {
super(props);
this.state = {
selectedOption: '',
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>Current Option: {this.state.selectedOption}</Text>
<Text
style={{ color: '#006381', marginTop: 20 }}
onPress={() => {
this.refs.picker.show();
}}
>
Click here to select your option
</Text>
<Text
style={{ color: '#006381', marginTop: 20 }}
onPress={() => {
this.refs.picker2.show();
}}
>
Click here to select your option with labels
</Text>
<SimplePicker
ref={'picker'}
options={options}
onSubmit={(option) => {
this.setState({
selectedOption: option,
});
}}
/>
<SimplePicker
ref={'picker2'}
options={options}
labels={labels}
itemStyle={{
fontSize: 25,
color: 'red',
textAlign: 'left',
fontWeight: 'bold',
}}
onSubmit={(option) => {
this.setState({
selectedOption: option,
});
}}
/>
</View>
);
}
}
// class ProposalPicker extends Component {
// state={proposal: ''}
// selectedValue = '';
// updateProposal = (proposal) => {
// this.setState({ proposal: this.selectedValue });
// }
// handleConfirmClick = () => {
// this.setState({ proposal: this.selectedValue });
// }
// render() {
// return (
// <View>
// <Picker selectedValue = {this.selectedValue}
// onValueChange = {this.updateProposal}
// itemStyle={{ backgroundColor: 'grey' }}
// >
// <Picker.Item label = "Test" value = "TestValue1" />
// <Picker.Item label = "Test 1" value = "TestValue2" />
// <Picker.Item label = "Test" value = "TestValue3" />
// <Picker.Item label = "Test" value = "TestValue4" />
// <Picker.Item label = "Test" value = "TestValue5" />
// <Picker.Item label = "Test" value = "TestValue6" />
// <Picker.Item label = "Test" value = "TestValue7" />
// <Picker.Item label = "Test" value = "TestValue8" />
// <Picker.Item label = "Test nothing" value = "TestValue9" />
// </Picker>
// <Text style = {styles.textStyle}>CONFIRM</Text>
// </View>
// )
// }
// }
const styles = {
proposalPickerStyle: {
backgroundColor: 'lightgrey'
},
textStyle: {
flex: 1
}
}
export default ProposalPicker;
ProposalPickerButton.js
import React from 'react';
import { View, Text, Image, TouchableOpacity } from 'react-native';
const PickerButton = ({ onPress, text }) => {
const { textStyle, iconStyle, iconContainerStyle, textContainerStyle, buttonStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<View style={styles.containerStyle}>
<View style={iconContainerStyle}>
<Image
style={iconStyle}
source={require('./images/201.png')}
/>
</View>
<View style={textContainerStyle}>
<Text style={textStyle}>{text}</Text>
</View>
<View style={iconContainerStyle}>
<Image
style={iconStyle}
source={require('./images/201.png')}
/>
</View>
</View>
</TouchableOpacity>
);
}
const styles = {
containerStyle: {
flex: 1,
//backgroundColor: 'red',
borderWidth: 2,
borderRadius: 0,
borderColor: '#FFFFFF',
//shadowColor: '#000',
//shadowOffset: { width: 0, height: 2 },
//shadowOpacity: 0.1,
//shadowRadius: 2,
//elevation: 1,
marginLeft: 40,
marginRight: 40,
marginTop: 10,
marginBottom: 10,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row'
},
iconContainerStyle: {
flex: 2,
//backgroundColor: 'blue',
justifyContent: 'center',
//alignItems: 'center',
//width: '20%',
//height: '20%'
},
iconStyle: {
flex: 1,
width: null,
height: null,
resizeMode: 'contain',
marginLeft: 10,
marginRight: 10,
marginTop: 10,
marginBottom: 10
},
textContainerStyle: {
flex: 8,
//backgroundColor: 'orange',
alignItems: 'flex-start',
justifyContent: 'center',
},
textStyle: {
fontSize: 20,
fontWeight: 'bold',
color: '#FFFFFF',
//marginLeft: 10
//padding: 18
},
buttonStyle: {
width: '100%',
height: '100%'
}
};
export default PickerButton;
App.js
import React, { Component } from 'react';
import { View, Text, ImageBackground } from 'react-native';
import Logo from './Logo';
import ProposalPickerButton from './ProposalPickerButton';
import Button from './Button';
import ProposalPicker from './ProposalPicker';
import SimplePicker from 'react-native-simple-picker';
class App extends Component {
render() {
return (
<ImageBackground
source={require('./images/city.png')}
style={styles.backgroundStyle}
>
<View style={styles.backgroundOverlayStyle} />
<View style={styles.container}>
<View style={styles.logoContainer}>
<Logo />
</View>
<View style={styles.proposalPickerButtonStyle}>
<ProposalPickerButton
onPress={() => new ProposalPicker().refs.picker.show()}
// onPress={() => console.log('Proposal picker button pressed')}
//onPress={() => Linking.openURL(url)}
text="Select a service line"
/>
</View>
<View style={styles.startProposalButtonStyle}>
<Button text="Start proposal"/>
</View>
<View style={styles.proposalPickerStyle}>
{/* <ProposalPicker /> */}
</View>
</View>
</ImageBackground>
);
}
}
const styles = {
backgroundStyle: {
flex: 1,
backgroundColor: '#000000',
width: '100%',
height: '100%',
position: 'absolute'
},
backgroundOverlayStyle: {
flex: 1,
position: 'absolute',
backgroundColor: '#003284',
opacity: 0.5,
width: '100%',
height: '100%'
},
container: {
//backgroundColor: 'red',
flex: 1,
//opacity: 0.5,
alignItems: 'center',
width: '100%',
height: '65%',
},
logoContainer: {
//backgroundColor: 'blue',
flex: 3,
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '65%',
},
proposalPickerButtonStyle: {
flex: 1,
//backgroundColor: 'yellow',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
marginLeft: 100,
marginRight: 100
},
startProposalButtonStyle: {
flex: 1,
//backgroundColor: 'purple',
width: '100%',
height: '100%',
marginTop: 10,
marginRight: 80
},
proposalPickerStyle: {
opacity: 1,
flex: 2,
backgroundColor: 'green',
width: '100%',
height: '100%'
},
};
export default App;
To call methods via refs you need to have a ref assigned to an already mounted component. Therefore you can't say new ProposalPicker().refs.picker.show() because refs.picker does not exist until the component is mounted. You Should have your button and picker components in the same parent, that way you can easily create a ref in that parent, assign it, and call methods from it:
Also you should use callback refs instead of string refs because string refs are deprecated. In that case it would look like:
constructor(props){
super(props)
this.state = ...
this.picker = React.createRef() // make the ref
}
Then assign the ref:
<SimplePicker
ref={this.picker}
And then you can make an function to call when your button is pressed:
showPicker = () => {
if (this.picker.current) {
this.picker.current.show()
}
}
I am trying to place an Avatar element over my TextInput so that it will look like a conventional search bar, but it doesn't go over the TextInput Please isn't it working, or can another better method of putting the search icon over the TextInput be suggested, Thank you
import { Avatar } from 'react-native-elements';
import FontAwesome
from './node_modules/#expo/vector-icons/fonts/FontAwesome.ttf';
import MaterialIcons
from './node_modules/#expo/vector-icons/fonts/MaterialIcons.ttf';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {timePassed: false};
}
state = {
fontLoaded: false
};
async componentWillMount() {
try {
await Font.loadAsync({
FontAwesome,
MaterialIcons
});
this.setState({ fontLoaded: true });
} catch (error) {
console.log('error loading icon fonts', error);
}
}
render() {
setTimeout(() => {
this.setState({timePassed: true})
}, 4000);
if (!this.state.timePassed) {
return <Splash/>;
} else {
return (
<View style={BackStyles.container}>
<Avatar style={BackStyles.searchIcon} icon={{ name: 'search', size: 25, }}/>
<TextInput placeholder="Search for your herbs.."
underlineColorAndroid={'transparent'} style={BackStyles.textBox}
/></View>
);
}
}
}
const BackStyles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'flex-start',
alignSelf: 'stretch',
flex: 1,
backgroundColor: '#E2E2E2',
marginTop: 20,
// width: '100%'
},
textBox: {
flex: 1,
height: 45,
padding: 4,
// textAlignVertical: 'top',
paddingLeft: 20,
// marginRight: 5,
flexGrow: 1,
// fontSize: 18,
color: '#000',
backgroundColor: '#fff',
// textAlign: 'center'
},
searchIcon:{
position: 'absolute',
alignSelf: 'stretch',
height: 45,
flex: 1,
top: 50,
flexGrow: 1,
padding: 4
}
});
You can use Flexbox's justifyContent feature to force the TextInput to the left and the search icon to the right. If you put a border on the container and not the TextInput, the entire thing will appear as there is a search icon fixed onto the right of the TextInput, when, in reality, they are two separate components.
// styles
const styles = StyleSheet.create({
searchBox: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
borderWidth: 1,
borderColor: 'black',
},
});
// the component
<View style={styles.searchBox}>
<TextInput ...yourprops />
<Avatar ...yourprops />
</View>
If you want to read more about justifyContent and how godly Flexbox is, you should check out Chris Coyier's Flexbox guide.
There seems to be a un-changeable margin on views using the react-native-scrollable-tab-view module. I can seem to get my code to fit to page on the views nested inside the scrollable-tab-view component. Any ideas? here's the code of the page presented:
'use strict';
import React from 'react';
import {
StyleSheet,
View,
Image,
Text,
TextInput
} from 'react-native';
//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
//modules/pages
var StepImage = require('../components/StepImage');
import Icon from 'react-native-vector-icons/FontAwesome';
import {Actions} from "react-native-router-flux";
var NavHeader = require('../components/Header');
var UserStat = require('../components/UserStat');
var UserCircle = require('../components/UserCircle');
var Button = require('../components/Button');
var Data = require('../stores/userDiets');
var NavigationBar = require('react-native-navbar');
var Profile = React.createClass({
getInitialState: function() {
return {
};
},
render: function() {
var Keywords = Data.diets;
return (
<View style={[styles.container]}>
<NavigationBar
style={{width: window.width}}
tintColor={'#50AE57'}
title={{title: 'Robert Greenfield', tintColor: 'white', style: {fontFamily: 'Nunito', fontSize: 18}}} />
<View style={[styles.header, this.border('red')]}>
<View style={[styles.userrow, this.border('red')]}>
<UserCircle source={require('../img/user/user.jpg')} style={styles.circle}/>
<View style={[styles.userinfo, this.border('orange')]}>
<View style={[styles.userstats, this.border('blue')]}>
<UserStat stat={3333} statTitle={'posts'} />
<UserStat stat={8888} statTitle={'achievements'} />
<UserStat stat={112} statTitle={'following'} />
<UserStat stat={'550K+'} statTitle={'followers'} />
</View>
<Icon.Button size={12} name="cogs" style={styles.edit} backgroundColor="#F4F4F4" onPress={this.loginWithFacebook}>
<Text style={styles.editText}>Edit Profile</Text>
</Icon.Button>
</View>
</View>
<View style={[styles.userBio, this.border('blue')]}>
<Text style={styles.userBioText}>The biggest #nutfree IG in the world. tag #nutfreenoms or #nomsy. To be featured, make an account at nomsy.co and post what you want shown! nomsy.co</Text>
</View>
<View style={styles.dietRow}>
{this.renderDiets(Keywords)}
</View>
</View>
</View>
);
},
renderDiets: function(diets) {
var that = this;
return diets.map(function(diet, i) {
return <View key={i} style={styles.box}><Text key={i} style={styles.userBioText}>{diet.name}</Text></View>
});
},
border: function(color) {
return {
//borderColor: color,
//borderWidth: 1,
}
}
});
var styles = StyleSheet.create({
box: {
margin: 2,
backgroundColor: '#56bf60',
borderRadius:2,
height: window.height/35,
padding: 3,
justifyContent: 'center'
},
dietRow:{
flexWrap: 'wrap',
flexDirection:'row',
height: window.height/20,
marginLeft: window.width/40,
width: window.width*0.96,
},
userBio: {
width: window.width*0.96,
alignItems: 'center',
marginLeft: window.width/80,
marginBottom: window.height/100
},
userBioText: {
color: 'black',
fontFamily: 'Nunito',
fontSize: 10
},
editText: {
color: 'white',
fontFamily: 'Nunito',
alignSelf: 'center'
},
edit: {
height: window.height/25,
justifyContent: 'center',
alignItems: 'center'
},
circle: {
width: window.width/5,
height: window.width/5,
borderRadius: window.width/10
},
userstats: {
flexDirection: 'row',
backgroundColor: 'white',
justifyContent: 'space-around',
marginBottom: window.height/100
},
userinfo: {
flexDirection: 'column',
backgroundColor: 'transparent',
width: window.width/1.4
},
userrow: {
flexDirection: 'row',
backgroundColor: 'transparent',
height: window.height/8,
justifyContent: 'space-around',
width: window.width
},
header: {
marginTop: window.height/50,
width: window.width,
flex: 0.9,
backgroundColor: 'white',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'flex-start',
},
});
module.exports = Profile;
And here's what it looks like:
You have to set automaticallyAdjustContentInsets={false} in your ListView (or ScrollView). Details here:
https://github.com/skv-headless/react-native-scrollable-tab-view/pull/174
https://github.com/facebook/react-native/issues/721
https://facebook.github.io/react-native/docs/scrollview.html#automaticallyadjustcontentinsets