I have created a table view using react-native list view.
I want to fix the header and first column in this table.
Here is what I created:
This list view is scrollable horizontally as well as vertically and all the data is dynamic.
I want to freeze the header and first column of this table if possible
Here is my code:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
ListView,
ScrollView,
Image,
TouchableOpacity,
Platform,
View
} from 'react-native';
import PMR from "../utilities/PMR";
import Spinner from 'react-native-loading-spinner-overlay';
import NavigationBar from 'react-native-navbar';
let bg = require('image!bg'),
back = require('image!back'),
Dimensions = require('Dimensions'),
windowSize = Dimensions.get('window'),
Screen = require('Dimensions').get('window');
class StationData extends Component {
constructor(props) {
super(props)
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
isVisible: true,
}
}
componentDidMount() {
let {username, password} = this.props.navigator.cerdentials;
let obj = {
'stXid':this.props.data.stationId,
'startTime':this.props.data.from,
'endTime':this.props.data.to
};
PMR.rawData(username, password, obj).then((rslt) => {
var RawData = [];
rslt.forEach(function(dataItem) {
if (dataItem.pointValue.length > 0)
RawData.push(dataItem);
});
RawData.unshift({name: 'Time', pointValue: rslt[0].pointValue})
// console.log(rslt)
this.setState({
dataSource: this.state.dataSource.cloneWithRows(RawData),
isVisible: false,
});
});
}
renderData(rowData) {
// console.log(rowData.pointValue);
if(rowData.name === 'Time'){
return (
<View>
<View style={{borderColor:'rgba(214, 214, 214,1)',borderWidth:1}}>
<View style={styles.names}>
<Text style={{marginHorizontal: 12, marginVertical:(Platform.OS === 'ios') ? 15 : 16}}>{rowData.name}</Text>
</View>
{rowData.pointValue.map((data) => <View style={{borderBottomWidth:1,borderColor:'rgba(214, 214, 214,1)',padding:8}}><Text>{data.time.split(" ")[1]}</Text></View>)}
</View>
</View>
);
} else {
return (
<View>
<View style={{borderColor:'rgba(214, 214, 214,1)',borderWidth:1}}>
<View style={styles.names}>
<Text style={{marginHorizontal: 12, marginVertical: 6.5}}>{rowData.name}</Text>
<Text>({rowData.engineeringUnit})</Text>
</View>
{rowData.pointValue.map((data) => <View style={{borderBottomWidth:1,borderColor:'rgba(214, 214, 214,1)',padding:8}}><Text>{isNaN(data.value) ? (data.value) : +(Math.round(data.value + "e+1") + "e-1")}</Text></View>)}
</View>
</View>
);
}
}
render() {
var titleConfig = {
title: `Station Data: ${this.props.data.stationName}`,
}
return (
<View style={styles.container}>
<Image style={styles.bg} source={bg} />
<Spinner visible={this.state.isVisible} />
<NavigationBar
title = {titleConfig}
leftButton={<TouchableOpacity onPress={() => this.props.navigator.pop()}>
<Image style={styles.back} source={back} />
</TouchableOpacity>}
style = {{backgroundColor:'rgba(244, 244, 244,1)'}} />
<ScrollView>
<View style={{position:'absolute', right:16, marginVertical:12}}>
<Text>{this.props.data.showDate}</Text>
</View>
<ListView
horizontal={true}
automaticallyAdjustContentInsets={false}
removeClippedSubviews={false}
enableEmptySections={true}
dataSource={this.state.dataSource}
renderRow={this.renderData}
style={styles.listView}
/>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
bg: {
position: 'absolute',
left: 0,
top: 0,
width: windowSize.width,
height: windowSize.height
},
names: {
backgroundColor:'rgba(219, 243, 207,1)',
borderBottomWidth:1,
borderColor:'rgba(214, 214, 214,1)',
alignItems:'center',
},
back:
{ marginTop:10,
marginLeft:10,
width:20,
height:20,
},
listView: {
marginVertical:(Screen.width/100)*10,
marginHorizontal:(Screen.width/100)*5
},
});
module.exports =StationData;
Related
Hi I am new to react native i am facing this error TypeError:undefined is not an object (evaluating this.state.items)
Another problem is it is returning me the data in an array how do i display the data as a string
import React, { Component } from "react";
import {StyleSheet,View,ActivityIndicator,FlatList,Text,TouchableOpacity} from "react-native";
export default class Source extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: "Source Listing",
headerStyle: {backgroundColor: "#fff"},
headerTitleStyle: {textAlign: "center",flex: 1}
};
};
constructor(props) {
super(props);
this.state = {
loading: false,
items:[]
};
this.fetchRequest=this.fetchRequest.bind.this
}
FlatListItemSeparator = () => {
return (
<View style={{
height: .5,
width:"100%",
backgroundColor:"rgba(0,0,0,0.5)",
}}
/>
);
}
componentDidMount()
{
fetchRequest();
}
renderItem=(data)=>
<TouchableOpacity style={styles.list}>
<Text style={styles.lightText}>{data.item.name}</Text>
<Text style={styles.lightText}>{data.item.email}</Text>
<Text style={styles.lightText}>{data.item.company.name}</Text>
</TouchableOpacity>
render(){
<FlatList
data= {this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()}
/>
fetchRequest()
{
const parseString = require('react-native-xml2js').parseString;
fetch('http://192.168.200.133/apptak_service/apptak.asmx/Get_Item_Master')
.then(response => response.text())
.then((response) => {
parseString(response, function (err, result) {
console.log(response)
});
}).catch((err) => {
console.log('fetch', err)
this.fetchdata();
})
if(this.state.loading){
return(
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9"/>
</View>
)}}
return(
<View style={styles.container}>
</View>
)}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff"
},
loader:{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
},
list:{
paddingVertical: 4,
margin: 5,
backgroundColor: "#fff"
}
});
Basically what i am trying to do is to get data from webservices and display the app on the screen
I am pretty new to React Native, so if the question seems stupid i am sorry in advance, i have been trying for hours to get this to work before asking this question.
I am trying to pass data from a text input to the next screen using firebase database.
I keep getting the error JSON Parse error: Unexpected identifier "undefined", I have attached below my two files, one with the text input (InputForm.js) and the other one which i want to show that data on the screen (ASTConfig1screen)
If anyone can help with this you really are a superstar!
InputForm.js
import React, { Component } from 'react';
import { StyleSheet, ScrollView, ActivityIndicator, View, TextInput } from 'react-native';
import { Button } from 'react-native-elements';
import firebase from '../Firebase';
import { withNavigation } from 'react-navigation';
class InputForm extends Component {
constructor() {
super();
this.ref = firebase.firestore().collection('boards');
this.state = {
name: '',
inventoryclass: '',
outlet: '',
isLoading: false,
};
}
updateTextInput = (text, field) => {
const state = this.state
state[field] = text;
this.setState(state);
}
saveBoard() {
this.setState({
isLoading: true,
});
this.ref.add({
name: this.state.name,
inventoryclass: this.state.inventoryclass,
outlet: this.state.outlet,
}).then((docRef) => {
this.setState({
name: '',
outlet: '',
inventoryclass: '',
isLoading: false,
});
this.props.navigation.navigate('ASTConfig1');
})
.catch((error) => {
console.error("Error adding document: ", error);
this.setState({
isLoading: false,
});
});
}
render() {
if(this.state.isLoading){
return(
<View style={styles.activity}>
<ActivityIndicator size="large" color="#ffa500"/>
</View>
)
}
return (
<ScrollView style={styles.container}>
<View style={styles.subContainer}>
<TextInput style={styles.inputtext}
placeholder={'Name'}
placeholderTextColor="white"
value={this.state.name}
onChangeText={(text) => this.updateTextInput(text, 'name')}
/>
</View>
<View style={styles.subContainer}>
<TextInput style={styles.inputtext}
multiline={true}
numberOfLines={4}
placeholder={'Inventory Class'}
placeholderTextColor="white"
value={this.state.inventoryclass}
onChangeText={(text) => this.updateTextInput(text, 'inventoryclass')}
/>
</View>
<View style={styles.subContainer}>
<TextInput style={styles.inputtext}
placeholder={'Outlet'}
placeholderTextColor="white"
value={this.state.outlet}
onChangeText={(text) => this.updateTextInput(text, 'outlet')}
/>
</View>
<View style={styles.button}>
<Button
large
leftIcon={{name: 'save'}}
title='Save'
onPress={() => this.saveBoard()} />
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20
},
subContainer: {
flex: 1,
marginBottom: 20,
padding: 5,
borderBottomWidth: 2,
borderBottomColor: '#CCCCCC',
},
inputtext: {
color: 'white',
fontSize: 20
},
activity: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
}
})
export default withNavigation(InputForm);
and this is where i would like to show the data on this screen
ASTConfig1.js
import React from 'react';
import {
View,
Text,
StyleSheet,
Button,
ImageBackground,
StatusBar,
SafeAreaView,
TextInput,
ScrollView,
UIManager,
ActivityIndicator
}
from 'react-native';
import {AccordionList} from "accordion-collapse-react-native";
import { Separator } from 'native-base';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import firebase from '../Firebase';
import Logo from '.././components/Logo';
import Colors from '.././constants/Colors';
import Search from '.././components/Search';
import InputForm from '.././components/InputForm';
class ASTConfig1Screen extends React.Component {
static navigationOptions = {
title: 'ASTConfig1',
};
constructor(props) {
super(props);
this.state= {
isLoading: true,
board: {},
key: '',
status:true,
text: '',
list:[
{
title: 'Getting Started',
body: 'React native Accordion/Collapse component, very good to use in toggles & show/hide content'
},
{
title: 'Components',
body: 'AccordionList,Collapse,CollapseHeader & CollapseBody'
},
{
title: 'Test',
body: 'AccordionList,Collapse,CollapseHeader & CollapseBody'
}
],
}
}
componentDidMount() {
const { navigation } = this.props;
const ref = firebase.firestore().collection('boards').doc(JSON.parse(navigation.getParam('boardkey')));
ref.get().then((doc) => {
if (doc.exists) {
this.setState({
board: doc.data(),
key: doc.id,
isLoading: false
});
} else {
console.log("No such document!");
}
});
}
_head(item){
return(
<Separator bordered style={{alignItems:'center'}}>
<Text>{item.title}</Text>
</Separator>
);
}
_body(item){
return (
<View style={{padding:10}}>
<Text style={{textAlign:'center'}}>{item.body}</Text>
</View>
);
}
ShowHideTextComponentView = () =>{
if(this.state.status == true)
{
this.setState({status: false})
}
else
{
this.setState({status: true})
}
}
render() {
if(this.state.isLoading){
return(
<View style={styles.activity}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
)
}
return (
<View style={styles.screen}>
<ImageBackground
source={require('.././assets/Img/BackGround2.png')}
style={styles.background}>
</ImageBackground>
<SafeAreaView>
<View style={{flex: 1, justifyContent: 'space-between', width: wp('80%')}}>
<View style={styles.logotop}>
<Logo/>
</View>
<View style={styles.editstock}>
<Text style={styles.editstocktext}>EDIT STOCK LIST:</Text>
</View>
{/*Start of 3 buttons Firebase*/}
<View style={styles.three}>
<View style={styles.edit1}>
<Text style={styles.textheader}>{this.state.board.name}</Text>
<Button style={styles.edit} title='Edit' ></Button>
</View>
<View style={{padding: 3}}></View>
<View style={styles.edit2}>
<Text style={styles.text}>{this.state.board.inventoryclass}</Text>
<Button style={styles.edit} title='Edit' ></Button>
</View>
<View style={styles.edit3}>
<Text style={styles.text}>{this.state.board.outlet}</Text>
<Button style={styles.edit} title='Edit' ></Button>
</View>
</View>
{/*End of 3 buttons Firebase*/}
{/*Start of AccordionList*/}
<ScrollView>
<View style={styles.middle}>
<AccordionList
list={this.state.list}
header={this._head}
body={this._body}
/>
</View>
</ScrollView>
{/*End of AccordionList*/}
{/*Start of Search*/}
<View>
{
this.state.status ? null : <View style={styles.bottom}>
<Text style={styles.textbottom}>SEARCH FOR NEW ITEMS:</Text>
<Search />
</View>
}
<Button title="ADD" onPress={this.ShowHideTextComponentView} />
</View>
</View>
</SafeAreaView>
</View>
);
};
};
{/*End of Search*/}
export default ASTConfig1Screen;
but it returns the error - Error adding document: [SyntaxError: SyntaxError: SyntaxError: JSON Parse error: Unexpected identifier "undefined"
in inputform.js saveBoard function you should
this.props.navigation.navigate('Details', {
'ASTConfig1': docRef
});
and remove JSON.parse form other file
the following code works fine on iOS, but on android after loading the orders array and rendering it, the onpress event stops working, at first I thought it was a problem with firebase but then I did it locally and I get the same issue.
import React from 'react';
import {
ActivityIndicator,
Alert,
Button,
Dimensions,
Image,
StatusBar,
StyleSheet,
ScrollView,
Text,
TouchableOpacity,
View,
Platform,
RefreshControl,
YellowBox } from 'react-native';
import { Ionicons as Icon } from '#expo/vector-icons';
import { Card, DefaultTheme } from 'react-native-paper';
import NavigationService from '../../Navigation/navigationService';
import _ from 'lodash';
YellowBox.ignoreWarnings(['Setting a timer']);
const _console = _.clone(console);
console.warn = message => {
if (message.indexOf('Setting a timer') <= -1) {
_console.warn(message);
}
};
import Firebase from '../../connection/to-firebase';
const LOGO_URL = 'https://i.imgur.com/BbYaucd.png';
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
const styles = StyleSheet.create({
container: {
paddingTop: StatusBar.currentHeight,
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT / 2,
backgroundColor: "#317AFA",
},
innerContainer: {width:SCREEN_WIDTH, alignItems: 'center', justifyContent: 'center' },
header: {position:'absolute', padding: 15, paddingTop: Platform.OS === 'ios' ? 13 : 7, marginTop:SCREEN_HEIGHT*0.05,zIndex:99 },
scrollView: {
position:'absolute',
top:SCREEN_HEIGHT*0.35,
marginHorizontal: 20,
width: SCREEN_WIDTH*0.90,
height: SCREEN_HEIGHT,
zIndex:9999
},
textHeader:{
marginTop:10,
color: 'white',
fontWeight: 'bold',
fontSize: 40,
}
});
const theme = {
colors: {
...DefaultTheme.colors,
primary: '#3498db',
accent: '#f1c40f',
}
}
export default class DefaultScreen extends React.Component {
constructor (props) {
super(props)
console.ignoredYellowBox = [
'Setting a timer'
];
this.state = {
orders: [],
refreshing: false,
timePassed: false
}
}
_onRefresh = () => {
this.setState({refreshing: true});
this.getOrders().then(() => {
this.setState({refreshing: false});
});
//setTimeout(()=>{this.setState({refreshing: false})},1000)
}
async getOrders(){
//let result = await Firebase.extractOrder();
let result = [
{
"Note": "",
"coords": {
"finalLatitude": 14.100751767597542,
"finalLongitude": -87.18541710839844,
"initialLatitude": 14.061113522979957,
"initialLongitude": -87.21807641015624
},
"createdAt": {
"nanoseconds": 686000000,
"seconds": 1576188983
},
"destinataryName": "Eliana MartÃnez",
"destinataryPhone": "97412032",
"idSubcategory": "1",
"idUsuario": 1,
"isTakenBySomeone": false,
"orderID": "rQAt5IEI687AkoI8rShh",
"products": [
{
"id": 93634,
"observation": "",
"price": "56.00",
"quantity": 1
},
{
"id": 29909,
"observation": "",
"price": "131.00",
"quantity": 97
}
],
"status": "Pending",
"telephone": 23456987,
"transportType": "Motocicleta"
}
]
this.setState({ orders: result});
}
componentDidMount(){
//this.getOrders();
}
renderOrders = (orders) =>{
return orders.map((a,b)=>{
return [
<MainOrders key={a.orderID} dName= {a.orderID} note ={a.Note} transType={a.transportType} orderDetails={a}
navigation={this.props.navigation}
/>
]
})
}
render() {
setTimeout(()=>{this.setState({timePassed: true})}, 1000);
if (!this.state.timePassed){
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
this.props.navigation.openDrawer();
}}
style = {{marginTop:'10%'}}
>
<Icon name="md-menu" size={35} color={'#fff'}/>
</TouchableOpacity>
<Text style={styles.textHeader}>Home</Text>
</View>
<View style={styles.innerContainer}>
<ScrollView style={styles.scrollView}
refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this._onRefresh}/>}
>
<Card theme={theme}>
<Card.Title title="Order List" subtitle="" />
<Card.Content>
<ActivityIndicator size="small" color="#317AFA" />
</Card.Content>
<Card.Actions>
<Button title="View Order" style={{zIndex:9999, elevation:15}} onPress={()=>{
Alert.alert('Hello World')
}}>View Order</Button>
</Card.Actions>
</Card>
</ScrollView>
</View>
</View>
);
}
else{
const {orders,navigation} = this.state;
DefaultScreen.navigationOptions = {
title: ''
}
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
this.props.navigation.openDrawer();
}}
style = {{marginTop:'10%'}}
>
<Icon name="md-menu" size={35} color={'#fff'}/>
</TouchableOpacity>
<Text style={styles.textHeader}>Home</Text>
</View>
<View style={styles.innerContainer}>
<ScrollView style={styles.scrollView}
refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this._onRefresh}/>}
>
<Card theme={theme}
>
<Card.Title title="Order List" subtitle="" />
<Card.Content>
{
orders.map((a,b)=>{
return [
<MainOrders key={a.orderID} dName= {a.orderID} note ={a.Note} transType={a.transportType} orderDetails={a}
navigation={this.props.navigation}
/>
]
})
}
</Card.Content>
<Card.Actions>
<Button title="Press me" style={{zIndex:9999}} onPress={()=>{
Alert.alert('Hello World')
}}> Press me</Button>
</Card.Actions>
</Card>
</ScrollView>
</View>
</View>
);
}
}
}
class MainOrders extends React.Component {
constructor() {
super();
}
render() {
return (
<View style={{marginTop:2,marginBottom:2}}>
<Card theme={theme}>
<Card.Title title={this.props.dName} subtitle={this.props.note} />
<Card.Content>
<Text>{this.props.transType}</Text>
</Card.Content>
<Card.Actions>
<Button title="view order" style={{zIndex:9999}} onPress={()=>{
this.props.navigation.navigate('orderDetails',{orderDetails: this.props.orderDetails})
}}> view order</Button>
</Card.Actions>
</Card>
</View>
);
}
}
I tried changing the execution orders,
setting timeout and when I manually filled out the order array was that I realized that the problem is at that point, but I can't see what I'm doing wrong.
"react-native": "0.59.8"
Thanks.
No matter what I try I can't seem to get my component to update. Below is my code:
import React, { Component } from "react";
import { StyleSheet, View, TouchableOpacity, Image, Text } from "react-native";
import PropTypes from "prop-types";
import { toggleSound } from "logic/Music.js";
import soundOn from "assets/img/swipe.png";
import soundOff from "assets/img/illum-triangle.png";
export default class GlobalSoundButton extends Component {
constructor(props) {
super(props);
this.state = {
audioOff: this.props.audioOff
};
}
componentDidUpdate = prevProps => {
if (prevProps.audioOff !== this.props.audioOff) {
this.setState({ audioOff: this.props.audioOff }, () => {
console.log("SWITCHING STATE", this.state);
};
this.forceUpdate();
}
};
render() {
return (
<View style={styles.soundButtonWrapper} key={this.props.name}>
<TouchableOpacity
style={styles.soundButtonPress}
activeOpacity={0.8}
onPress={() => {
toggleSound(this.props.sounds);
}}
>
<Image
style={styles.soundButton}
source={this.state.audioOff ? soundOff : soundOn}
></Image>
<Text style={styles.text}>
Audio {this.state.audioOff ? "off" : "on"}
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
soundButtonWrapper: {
width: "100%",
height: 40,
position: "absolute",
top: 20
},
soundButtonPress: {
width: 40,
height: 40,
position: "absolute",
right: 20
},
soundButton: {
width: 40,
height: 40,
tintColor: "#59BC92"
},
text: {
width: 120,
height: 40,
position: "absolute",
right: 80,
color: "white"
}
});
GlobalSoundButton.propTypes = {
sounds: PropTypes.array
};
The weird part is that I'm using this component in two different screens and in one case it works absolutely fine but in the other screen it doesn't re-render when the audio is changed.
Every time I press it the props get updated so I KNOW that the state updates. The console log always writes out different state so I know the state is updated. I also tried forceUpdate() and adding a key (you can see the key in the code) but it doesn't help.
I'm at a loss here. Has anyone bumped into the same issue or can help? I also know there are several questions quite like this one but no one answered my questions so I had to write my own.
I removed a lot of unrelated code here but basically I pass the props down the following way in my HomeScreen (it's the GlobalSoundButton, and in this case it works):
import GLOBAL from "logic/GlobalState.js";
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
audioOff: false,
};
}
async componentDidMount() {
let audioOff;
try {
audioOff = await retrieveData("audioOff");
} catch (err) {
console.error(err);
}
this.setState(
{
audioOff: audioOff === "true"
});
render() {
GLOBAL.homeScreen = this;
return (
<View style={styles.container}>
<View style={styles.bg}>
<ImageBackground
source={pattern}
style={styles.img}
resizeMode="repeat"
imageStyle={styles.innerImg}
/>
</View>
<View style={styles.container}>
<GlobalSoundButton
sounds={this.state.allSounds}
audioOff={this.state.audioOff}
name="HomeScreenKey"
></GlobalSoundButton>
<Text
style={[styles.smallText, styles.ppText]}
onPress={() =>
Linking.openURL(
"https://privacy-illuminati-flip.netlify.com"
).catch(err => console.error("An error occurred", err))
}
>
Privacy Policy
</Text>
<Text style={styles.welcome}>Illuminati Flip</Text>
<TouchableWithoutFeedback
onPressIn={evt => this.grabFinger(evt)}
onPressOut={evt => this.swipe(evt)}
pressRetentionOffset={{ top: 100, left: 0, bottom: 100, right: 0 }}
>
<View style={styles.swipeArea}>
<View style={styles.gridSelection}>
<Animated.View
pointerEvents={"none"}
style={{
...styles.innerGridSelection,
transform: [{ translateX: this.springValue }]
}}
>
{difficulties}
</Animated.View>
</View>
<View style={styles.margin}>
<Animated.Image
source={swipeFinger}
style={{
...styles.hand,
transform: [
{
translateX: this.fingerValue.interpolate({
inputRange: [-1, 1],
outputRange: [-15, 15]
})
}
]
}}
/>
<Text style={styles.smallText}>Swipe to change difficulty</Text>
</View>
</View>
</TouchableWithoutFeedback>
<TouchableOpacity
activeOpacity={0.8}
onPress={() => {
this.checkTutorial();
}}
>
<Text style={styles.button}>Begin Ceremony</Text>
</TouchableOpacity>
<Text
style={[styles.smallText, styles.musicText]}
onPress={() =>
Linking.openURL("https://fanlink.to/triobgame").catch(err =>
console.error("An error occurred", err)
)
}
>
Music by #triobelisk
</Text>
<Text
style={[styles.smallText, styles.devText]}
onPress={() =>
Linking.openURL("https://twitter.com/iamjohnhult").catch(err =>
console.error("An error occurred", err)
)
}
>
Developed by #iamjohnhult
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
...
});
The difference in my other component where it doesn't work I render it like this:
import GLOBAL from "logic/GlobalState.js";
<GlobalSoundButton
sounds={this.state.allSounds}
audioOff={GLOBAL.homeScreen.state.audioOff}
name="GameScreenKey"
></GlobalSoundButton>
And the GlobalState.js is as follows:
module.exports = {
homeScreen: null
};
I have created custom tabs in react-native but I am unable to select a tab. I have initialized the state for the selected tab but do not know where to set the state.
here is my code:
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Image,
View
} from 'react-native';
var Dimensions = require('Dimensions');
var windowSize = Dimensions.get('window');
var bg = require('image!bg');
class TabView extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'list',
selectedTab: 'map'
};
}
render() {
return (
<View style={styles.container}>
<Image style={styles.bg} source={bg} />
<View style={styles.tabView}>
<View style={[styles.listView,styles.selectedView]}>
<Text>List View</Text>
</View>
<View style={[styles.listView,{}]}>
<Text>Map View</Text>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
bg: {
position: 'absolute',
left: 0,
top: 0,
width: windowSize.width,
height: windowSize.height
},
tabView: {
flexDirection: 'row',
//bottom: 200,
borderWidth:2,
borderColor:'rgba(4, 193, 3,1)',
borderRadius: 5,
marginHorizontal: 20,
marginTop: 50
},
listView: {
flex: 2,
padding:7,
alignItems:'center'
},
mapView: {
flex: 2,
padding:7,
alignItems:'center'
},
selectedView: {
backgroundColor:'rgba(4, 193, 3,1)',
color: 'white'
}
});
module.exports = TabView
I just want to know where shall I add a check so that I can make a difference in the selected tab
Any help will be appreciated.
Please, check out the code here, to get an idea how it can be done
const Tab = (props) => {
let style = props.isSelected && styles.selectedTab || styles.normalTab;
return (
<View style={style}>
<TouchableHighlight onPress={() => props.onTabPress(props.id)}>
<Text>{props.title}</Text>
</TouchableHighlight>
</View>
)
}
class TabsView extends Component {
constructor(props) {
super(props)
this.state = {
selectedTab: 'one'
}
}
render() {
return (
<View>
<Tab onTabPress={this.onSelectTab.bind(this)} title="One" id="one" isSelected={this.state.selectedTab == "one"}/>
<Tab onTabPress={this.onSelectTab.bind(this)} title="Two" id="two" isSelected={this.state.selectedTab == "two"}/>
</View>
)
}
onSelectTab(selectedTab) {
this.setState({ selectedTab })
}
}
The above code splits your component in two parts, a logical part (TabsView) and a dumb presentational part (Tab)
The logical handles the clickHandler (onSelectTab) which is passed as a prop (onTabPress) to the dumb (Tab) Component.
I just want to know where shall I add a check so that I can make a difference in the selected tab
In the render method, it should go
example:
render() {
let FirstTabStyles = Object.assign(
defaultTabStyles,
(isFirstSelected && selectedStyles || {})
)
let SecondTabStyle = Object.assign(
defaultTabStyles,
(isSecondSelected && selectedStyles || {})
)
return (
<View>
<FirstTab style={FirstTabStyle} />
<SecondTab style={SecondTabStyle} />
</View>
)
}