Related
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
TouchableOpacity,
Alert,
Image,
Button,
TextInput,
Dimensions
} from "react-native";
import { Dialog } from "react-native-simple-dialogs";
import AsyncStorage from "#react-native-community/async-storage";
import { KeyboardAvoidingView } from "react-native";
import DropdownAlert from "react-native-dropdownalert";
import { BoxShadow } from "react-native-shadow";
import { DrawerActions } from "react-navigation-drawer";
import MapView, { PROVIDER_GOOGLE } from "react-native-maps";
import datum from "./data";
import { Marker } from "react-native-maps";
import Parse from "parse/react-native";
import Geolocation from "react-native-geolocation-service";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
const homePlace = {
description: "Home",
geometry: {
location: {
lat: 48.8152937,
lng: 2.4597668
}
}
};
const workPlace = {
description: "Work",
geometry: {
location: {
lat: 48.8496818,
lng: 2.2940881
}
}
};
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
lat: 12.9122536,
long: 80.0987121,
picklat: 12.9122536,
picklong: 80.0987121,
droplat: 12.9202954,
droplong: 80.1026819,
curautostate: "pick",
curautostateplaceholder: "Enter your pick up location",
distance: 0,
windowwidth: Dimensions.get("window").width,
windowheight: Dimensions.get("window").height
};
}
componentDidMount() {
Geolocation.requestAuthorization();
Geolocation.getCurrentPosition(
position => {
this.setState({
lat: position.coords.latitude
});
this.setState({
long: position.coords.longitude
});
this.setState({
picklat: position.coords.latitude
});
this.setState({
picklong: position.coords.longitude
});
this.setState({
droplat: position.coords.latitude
});
this.setState({
droplong: position.coords.longitude
});
},
error => {
Alert.alert(
"Please enable the location service",
error.message,
[
{
text: "OK",
onPress: () => console.log("has to exit")
}
],
{
cancelable: false
}
);
},
{
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 10000
}
);
}
tooglestate = getstate => {
if (getstate == "drop") {
this.setState({
curautostate: "drop"
});
this.setState({
curautostateplaceholder: "Enter your drop location"
});
this.setState({
lat: this.state.droplat,
long: this.state.droplong
});
} else if (getstate == "pick") {
this.setState({
curautostate: "pick"
});
this.setState({
curautostateplaceholder: "Enter your pick location"
});
this.setState({
lat: this.state.picklat,
long: this.state.picklong
});
} else {
}
};
executeautocompleteView = text => {
console.log(text);
};
render() {
return (
<View
style={{
flex: 1,
flexDirection: "column",
backgroundColor: datum.secondaryColor
}}
>
<View
style={{
backgroundColor: "#E8EDF1",
width: "100%",
height: "9%",
top: 0,
zIndex: 1,
shadowColor: datum.secondaryColor,
elevation: 20,
flexDirection: "column"
}}
>
<Image
source={require("./Drawbles/Homeicon.png")}
resizeMode="contain"
style={{
width: "10%",
height: "100%",
alignSelf: "center"
}}
/>
</View>
<MapView
style={styles.map}
initialRegion={{
latitude: this.state.lat,
longitude: this.state.long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
region={{
latitude: this.state.lat,
longitude: this.state.long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
>
<Marker
draggable
coordinate={{
latitude: this.state.picklat,
longitude: this.state.picklong
}}
pinColor={"#56954A"}
onDragEnd={e => {
this.setState({
picklat: e.nativeEvent.coordinate.latitude,
picklong: e.nativeEvent.coordinate.longitude,
lat: e.nativeEvent.coordinate.latitude,
long: e.nativeEvent.coordinate.longitude
});
}}
/>
<Marker
draggable
coordinate={{
latitude: this.state.droplat,
longitude: this.state.droplong
}}
pinColor={"#C5441B"}
onDragEnd={e =>
this.setState({
droplat: e.nativeEvent.coordinate.latitude,
droplong: e.nativeEvent.coordinate.longitude,
lat: e.nativeEvent.coordinate.latitude,
long: e.nativeEvent.coordinate.longitude
})
}
/>
</MapView>
<View
style={{
flexDirection: "row",
backgroundColor: datum.secondaryColor,
zIndex: 1,
alignSelf: "center",
top: "10%",
height: this.state.windowheight * 0.07,
width: this.state.windowwidth * 0.9,
shadowColor: datum.secondaryColor,
elevation: 20
}}
>
<TouchableOpacity onPress={() => this.tooglestate("pick")}>
<View
style={{
width: this.state.windowwidth * 0.13,
height: this.state.windowheight * 0.07,
backgroundColor: "#56954A"
}}
/>{" "}
</TouchableOpacity>
<GooglePlacesAutocomplete
placeholder="Search"
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={"search"} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
keyboardAppearance={"light"} // Can be left out for default keyboardAppearance https://facebook.github.io/react-native/docs/textinput.html#keyboardappearance
listViewDisplayed="auto" // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
getDefaultValue={() => ""}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: "6Iza4Sy3APa34ewekfaM3yZB-Tt6SNO4",
language: "en", // language of the results
types: "(cities)" // default: 'geocode'
}}
styles={{
textInputContainer: {
width: "100%",
backgroundColor: datum.primaryColor
},
description: {
fontWeight: "bold"
},
textInput: {
backgroundColor: datum.primaryColor
},
predefinedPlacesDescription: {
color: datum.primaryColor
}
}}
currentLocationLabel="Current location"
nearbyPlacesAPI="GooglePlacesSearch" // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={
{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}
}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: "distance",
type: "cafe"
}}
GooglePlacesDetailsQuery={{
// available options for GooglePlacesDetails API : https://developers.google.com/places/web-service/details
fields: "formatted_address"
}}
filterReverseGeocodingByTypes={[
"locality",
"administrative_area_level_3"
]} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
/>
<TouchableOpacity onPress={() => this.tooglestate("drop")}>
<View
style={{
width: this.state.windowwidth * 0.13,
height: this.state.windowheight * 0.07,
backgroundColor: "#C5441B"
}}
/>{" "}
</TouchableOpacity>
</View>
<View
style={{
backgroundColor: datum.secondaryColor,
width: "100%",
height: "9%",
top: "90%",
zIndex: 2,
shadowColor: datum.secondaryColor,
elevation: 20,
flexDirection: "row"
}}
/>
<DropdownAlert ref={ref => (this.dropdown = ref)} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
map: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 2
},
headertext: {
fontSize: 20,
textAlign: "center",
color: datum.secondaryColor,
margin: 10
},
bookingbar: {
flex: 1,
flexDirection: "row",
height: "30%",
width: "100%",
zIndex: 30,
bottom: 0
}
});
I am trying to align the Last view comp to top '90%' but somehow my layout breaks I don't know what went wrong, my black view is supposed to be at the bottom edge of the comp but it slight align up where it suppose to be, I have tried using point/and percentages but nothing seems to work, I don't where is the mistake is that with me or with react native library
You are missing the absolute position property, try this:
<View style={{
backgroundColor: 'blue',
position: 'absolute',
width: '100%',
height: '10%',
top: '90%',
zIndex: 2,
shadowColor: 'black',
elevation: 20,
flexDirection: 'row'
}}/>
Im trying to play full screen video using react native video, how can I play video full screen for both android and ios?in my case ios playing full screen correctly and in android video is stretched.
for landscape mode I used transform: [{ rotate: '90deg' }], its works but in android the video screen in stretched
Your help is highly appreciated.
here is my code
return (
<View onLayout={this.onLayout.bind(this)} style={styles.fullScreen} key={this.state.key}>
<View style={styles.backButtonWrapper}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Image source={Share} />
</TouchableOpacity>
</View>
<TouchableOpacity
style={styles.videoView}
onPress={this.playOrPauseVideo.bind(this, paused)}>
<Video
ref={videoPlayer => this.videoPlayer = videoPlayer}
onEnd={this.onVideoEnd.bind(this)}
onLoad={this.onVideoLoad.bind(this)}
onProgress={this.onProgress.bind(this)}
source={{ uri: this.props.detailedWorkout.videoLink }}
paused={paused}
volume={Math.max(Math.min(1, volume), 0)}
resizeMode="none"
style={styles.videoContainer} />
{paused &&
<View style={styles.pauseImageWrapper}>
<Image style={styles.videoIcon} source={PlayButton} />
</View>
}
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1
},
backgroundVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
fullScreen: {
flex: 1,
backgroundColor: "white"
},
videoView: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
videoContainer: {
width: Dimensions.get('window').height,
height: Dimensions.get('window').width,
minWidth: Dimensions.get('window').height,
minHeight: Dimensions.get('window').width,
width: Dimensions.get('screen').height,
height: Dimensions.get('screen').width,
transform: [{ rotate: '90deg' }],
},
videoIcon: {
width: 50,
height: 50
},
pauseImageWrapper: {
alignItems: 'center',
alignSelf: 'center',
position: "absolute",
},
backButtonWrapper: {
backgroundColor: 'red',
position: 'absolute',
zIndex: 1,
alignSelf: "flex-end"
}
});
I solve the issue using react-native-orientation.I'll post my code for anyone who having this issue.Cheers thanks for your help
import React, { Component, PropTypes } from "react";
import {
View,
Dimensions,
StyleSheet,
TouchableOpacity,
Image,
StatusBar,
Platform,
} from "react-native";
import {
Share,
PlayButton
} from "../../config/images";
import {
TextLogo,
IconWithCount,
DefaultIcon,
ClickableIcon,
} from "../../mixing/UI";
import {
WorkoutDetail,
KeyValueText,
DetailText,
ProgressController
} from "../../components";
import Orientation from "react-native-orientation";
import Video from "react-native-video"
const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;
let FORWARD_DURATION = 7;
export default class VideoPlayer extends Component {
constructor(props, context, ...args) {
super(props, context, ...args);
this.state = { paused: false };
}
componentDidMount() {
Orientation.lockToLandscapeLeft();
}
componentWillUnmount() {
Orientation.lockToPortrait();
}
componentWillMount() {
StatusBar.setHidden(true);
Orientation.lockToLandscapeLeft();
}
onVideoEnd() {
this.videoPlayer.seek(0);
this.setState({ key: new Date(), currentTime: 0, paused: true });
}
onVideoLoad(e) {
this.setState({ currentTime: e.currentTime, duration: e.duration });
}
onProgress(e) {
this.setState({ currentTime: e.currentTime });
}
playOrPauseVideo(paused) {
this.setState({ paused: !paused });
}
onBackward(currentTime) {
let newTime = Math.max(currentTime - FORWARD_DURATION, 0);
this.videoPlayer.seek(newTime);
this.setState({ currentTime: newTime })
}
onForward(currentTime, duration) {
if (currentTime + FORWARD_DURATION > duration) {
this.onVideoEnd();
} else {
let newTime = currentTime + FORWARD_DURATION;
this.videoPlayer.seek(newTime);
this.setState({ currentTime: newTime });
}
}
getCurrentTimePercentage(currentTime, duration) {
if (currentTime > 0) {
return parseFloat(currentTime) / parseFloat(duration);
} else {
return 0;
}
}
onProgressChanged(newPercent, paused) {
let { duration } = this.state;
let newTime = newPercent * duration / 100;
this.setState({ currentTime: newTime, paused: paused });
this.videoPlayer.seek(newTime);
}
onLayout(e) {
const { width, height } = Dimensions.get('window')
}
goBack = () => {
this.props.navigation.goBack();
Orientation.lockToPortrait();
}
// navigation options
static navigationOptions = { header: null }
// render
render() {
let { onClosePressed, video, volume } = this.props;
let { currentTime, duration, paused } = this.state;
const completedPercentage = this.getCurrentTimePercentage(currentTime, duration) * 100;
return (
<View onLayout={this.onLayout.bind(this)} style={styles.fullScreen} key={this.state.key}>
<View style={styles.backButtonWrapper}>
<TouchableOpacity onPress={() => this.goBack()}>
<Image source={Share} />
</TouchableOpacity>
</View>
<TouchableOpacity
style={styles.videoView}
onPress={this.playOrPauseVideo.bind(this, paused)}>
<Video
ref={videoPlayer => this.videoPlayer = videoPlayer}
onEnd={this.onVideoEnd.bind(this)}
onLoad={this.onVideoLoad.bind(this)}
onProgress={this.onProgress.bind(this)}
source={{ uri: this.props.detailedWorkout.videoLink }}
paused={paused}
volume={Math.max(Math.min(1, volume), 0)}
resizeMode="none"
style={Platform.OS === "android" ? styles.videoContainerAndroid : styles.videoContainerIOS} />
{paused &&
<View style={styles.pauseImageWrapper}>
<Image style={styles.videoIcon} source={PlayButton} />
</View>
}
</TouchableOpacity>
</View>
);
}
}
// styles
const styles = StyleSheet.create({
fullScreen: {
flex: 1,
backgroundColor: "black"
},
videoView: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
videoContainerAndroid: {
height: "100%",
width: "100%"
},
videoContainerIOS: {
width: Dimensions.get('window').height,
height: Dimensions.get('window').width,
minWidth: Dimensions.get('window').height,
minHeight: Dimensions.get('window').width,
width: Dimensions.get('screen').height,
height: Dimensions.get('screen').width,
transform: [{ rotate: '90deg' }],
},
videoIcon: {
width: 50,
height: 50
},
pauseImageWrapper: {
alignItems: 'center',
alignSelf: 'center',
position: "absolute",
},
backButtonWrapper: {
backgroundColor: 'red',
position: 'absolute',
zIndex: 1,
alignSelf: "flex-end"
}
});
Try resizeMode="contain" (documentation)
For some reason 2 Amazon Kindles that I have for testing running the latest updates (Android 5.1.1) is producing just a solid green colour when capturing with React-Native-Camera.
I've also tested on my Xiaomi Mi6, a Mi5 and also an Asus Zen 8" Tablet, all working fine, but the Kindle produces this weired outcome... What's really strange is the viewfinder is fine, it looks as if it'll take a picture but doesn't. The Front Facing camera is fine also.
Using react-native-camera: ^1.1.4
Capture.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, ActivityIndicator } from 'react-native';
import { Avatar } from 'react-native-elements';
import { RNCamera } from 'react-native-camera';
import { inject, observer } from 'mobx-react/native';
import ImagePicker from 'react-native-image-crop-picker';
let Type = null;
const typeArr = [
{ Name: 'Front', Type: RNCamera.Constants.Type.front },
{ Name: 'Back', Type: RNCamera.Constants.Type.back },
{ Name: null, Type: RNCamera.Constants.Type.back },
];
const styles = StyleSheet.create({
entryTitle: {
fontSize: 22,
fontWeight: '700',
},
container: {
flex: 1,
flexDirection: 'column',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.8)',
},
});
#inject('store')
#observer
export default class Capture extends Component {
constructor(props) {
super(props);
this.state = { Type: RNCamera.Constants.Type.back, CaptureInProgress: false };
Type =
this.props.navigation.state.params.Type == null
? null
: this.props.navigation.state.params.Type;
}
state = {
Type: typeArr.find(element => element.Name === Type).Type,
};
barcodeScanned(response) {
this.props.store.CaptureStore.captureData = response.data;
this.props.navigation.state.params.AfterCapture();
this.props.navigation.goBack();
}
takePicture = async function () {
if (this.camera) {
this.setState({ CaptureInProgress: true });
const options = { quality: 0.5, base64: true, fixOrientation: true };
const data = await this.camera.takePictureAsync(options);
this.props.store.CaptureStore.captureData = data.base64;
this.props.navigation.state.params.AfterCapture();
this.setState({ CaptureInProgress: false });
this.props.navigation.goBack();
}
};
openGallery() {
ImagePicker.openPicker({
width: 300,
height: 400,
cropping: true,
includeBase64: true,
}).then((image) => {
this.props.store.CaptureStore.captureData = image.data;
this.props.navigation.state.params.AfterCapture();
this.props.navigation.goBack();
});
}
switchCamera() {
if (this.state.Type === RNCamera.Constants.Type.back) {
this.setState({ Type: RNCamera.Constants.Type.front });
} else {
this.setState({ Type: RNCamera.Constants.Type.back });
}
}
renderTakePhotoButton() {
if (this.props.navigation.state.params.Mode === 'photo') {
return (
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Avatar
medium
rounded
icon={{ name: 'refresh', color: 'grey', type: 'font-awesome' }}
onPress={() => this.switchCamera()}
activeOpacity={1}
/>
<Avatar
large
rounded
icon={{ name: 'camera', color: 'grey' }}
onPress={() => this.takePicture()}
activeOpacity={1}
/>
<Avatar
medium
rounded
icon={{ name: 'folder-open-o', color: 'grey', type: 'font-awesome' }}
onPress={() => this.openGallery()}
activeOpacity={1}
/>
</View>
);
}
return null;
}
render() {
return (
<View style={styles.container}>
<View
style={{
height: '10%',
padding: 10,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={styles.entryTitle}>{this.props.navigation.state.params.Title}</Text>
</View>
<View
style={{
height: this.props.navigation.state.params.Mode === 'photo' ? '75%' : '90%',
flexDirection: 'column',
}}
>
<RNCamera
ref={(ref) => {
this.camera = ref;
}}
style={styles.preview}
barCodeTypes={
this.props.navigation.state.params.Mode === 'qr'
? [RNCamera.Constants.BarCodeType.qr]
: []
}
type={this.state.Type}
// flashMode={RNCamera.Constants.FlashMode.on}
permissionDialogTitle="Permission to use camera"
permissionDialogMessage="We need your permission to use your camera phone"
onBarCodeRead={response => this.barcodeScanned(response)}
/>
</View>
{this.renderTakePhotoButton()}
{this.state.CaptureInProgress && (
<View style={styles.loading}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
)}
</View>
);
}
}
Specifically, it all happens in 'takePicture', the afterCapture just handles the consumption of the base64 that is temporarily in the CaptureStore...
Fixed in React-Native-Camera 1.1.5
I am trying to send an array and a key to another screen using StackNavigator, but it tells me that the program does not see the getNoteArray() function.
getNoteArray(){
return this.state.noteArray;
}
editMethod(key){
const {navigate} = this.props.navigation;
navigate('EditNote' , {noteArray: this.getNoteArray(), key});
}
Here is the EditNote screen:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
AsyncStorage,
} from 'react-native';
import Note from './Note.js';
export default class EditNote extends Component {
static navigationOptions = {
title: 'Edit',
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
}
componentDidMount(){
this.setState({noteArray: this.props.navigation.state.params.noteArray})
alert(this.state.noteArray);
}
render() {
const {params} = this.props.navigation.state;
return (
<View style={styles.container}>
<View style={styles.noteBody}>
<TextInput
multiline = {true}
numberOfLines = {1000000}
style={styles.textInput}
placeholderTextColor='grey'
underlineColorAndroid='transparent'>
</TextInput>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
noteBody:{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 10,
alignItems: 'center',
borderBottomWidth:1,
borderTopColor: '#000',
marginBottom: 100,
},
textInput: {
alignSelf: 'stretch',
textAlignVertical: 'top',
backgroundColor: '#fff',
color: '#000',
padding: 20,
borderTopWidth:2,
borderTopColor: '#ededed',
},
addButton: {
position: 'absolute',
zIndex: 11,
left: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
width: 300,
backgroundColor: '#00FF00',
height: 60,
elevation: 8
},
addButtonText: {
color: '#fff',
fontSize: 24,
},
});
You can try like this
editMethod(key){
const {navigate} = this.props.navigation;
navigate('EditNote',{ params1:'hello',params2:'hi'});
}
https://reactnavigation.org/docs/en/navigation-prop.html#navigate-link-to-other-screens
The syntax is
navigation.navigate({routeName, params, action, key})
OR
navigation.navigate(routeName, params, action)
So it can be
navigate('EditNote' , { notesArray: getNoteArray(), key} );
OR
navigate({
routeName: 'EditNote' ,
params: {
notesArray: getNoteArray(),
key
}
});
I am new to react-native. In my app, I'm using a switch and changing the tint color to differentiate ON and OFF, but my actual requirement is to show "YES" or "NO" text inside the switch like below.
Here is my Code:
<Switch
onValueChange={this.change.bind(this)}
style={{marginBottom:10,width:90,marginRight:6,marginLeft:6}}
value={true}
thumbTintColor="#0000ff"
tintColor="#ff0000"
/>
Please give me suggestions to solve this issue, Any help much appreciated.
Finally I got the On off inside switch .......
install
npm install --save react-native-switch
import { Switch } from 'react-native-switch';
<Switch
value={true}
onValueChange={(val) => console.log(val)}
disabled={false}
activeText={'On'}
inActiveText={'Off'}
backgroundActive={'green'}
backgroundInactive={'gray'}
circleActiveColor={'#30a566'}
circleInActiveColor={'#000000'}/>
Refer this link...
https://github.com/shahen94/react-native-switch
I would start with something like this and then iterate and polish until it fulfills the requirements and looks good. This isn't a complete solution but should give you some ideas.
import React from 'react';
import { LayoutAnimation, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
const styles = StyleSheet.create({
container: {
width: 80,
height: 30,
backgroundColor: 'grey',
flexDirection: 'row',
overflow: 'visible',
borderRadius: 15,
shadowColor: 'black',
shadowOpacity: 1.0,
shadowOffset: {
width: -2,
height: 2,
},
},
circle: {
width: 34,
height: 34,
borderRadius: 17,
backgroundColor: 'white',
marginTop: -2,
shadowColor: 'black',
shadowOpacity: 1.0,
shadowOffset: {
width: 2,
height: 2,
},
},
activeContainer: {
backgroundColor: 'blue',
flexDirection: 'row-reverse',
},
label: {
alignSelf: 'center',
backgroundColor: 'transparent',
paddingHorizontal: 6,
fontWeight: 'bold',
},
});
class LabeledSwitch extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
};
this.toggle = this.toggle.bind(this);
}
componentWillReceiveProps(nextProps) {
// update local state.value if props.value changes....
if (nextProps.value !== this.state.value) {
this.setState({ value: nextProps.value });
}
}
toggle() {
// define how we will use LayoutAnimation to give smooth transition between state change
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
const newValue = !this.state.value;
this.setState({
value: newValue,
});
// fire function if exists
if (typeof this.props.onValueChange === 'function') {
this.props.onValueChange(newValue);
}
}
render() {
const { value } = this.state;
return (
<TouchableOpacity onPress={this.toggle}>
<View style={[
styles.container,
value && styles.activeContainer]}
>
<View style={styles.circle} />
<Text style={styles.label}>
{ value ? 'YES' : 'NO' }
</Text>
</View>
</TouchableOpacity>
);
}
}
LabeledSwitch.propTypes = {
onValueChange: React.PropTypes.func,
value: React.PropTypes.bool,
};
LabeledSwitch.defaultProps = {
};
export default LabeledSwitch;