positioning react elements - javascript

The following code works but wondering if this is really the best way to accomplish the task at hand. Two TextInput fields, when show = true display both of them. When show = false display the first one in the same position on the screen and not display the second one. We've substituted a blank Text element to take up the space of the second TextInput element. Is that the right way to do this? It seems a little hokey.
import React from 'react';
import { StyleSheet, TextInput, View, Button, Text } from 'react-native';
export default class App extends React.Component {
state={show: true,}
handleElement(){}
handleKey(){}
onSubmit=()=>{
this.setState({show:!this.state.show})
// this.setState(prevState =>({show:!prevState.show}))
}
render() {
return (
<View style={styles.container}>
{ this.state.show &&
<View>
<TextInput style={styles.input}
placeholder='Element'
onChangeText={this.handleElement} />
<TextInput style={styles.input}
placeholder='Key'
onChangeText={this.handleKey}/>
<Button title='Add' onPress={this.onSubmit} />
</View>
}
{ !this.state.show &&
<View>
<TextInput style={styles.input}
placeholder='Element'
onChangeText={this.handleElement} />
<Text style={styles.blank}> </Text>
<Button title='Add' onPress={this.onSubmit} />
</View>
}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
input: {
padding:5,
borderColor:'black',
borderWidth:1,
width:100,
marginTop:5,
},
blank: {
borderColor:'white',
borderWidth:1,
padding:5,
width:100,
marginTop:5,
},
});

You can take advantage of Flex positioning to achieve this. Also the layout can be simplified to something like:
render() {
return (
<View style={styles.container}>
<View style={styles.wrapper}>
<TextInput
style={styles.input}
placeholder='Element'
onChangeText={this.handleElement}
/>
{
this.state.show &&
<TextInput
style={styles.input}
placeholder='Key'
onChangeText={this.handleKey}
/>
}
<Button title='Add' onPress={this.onSubmit} />
</View>
</View>
)
}
The styles for the wrapper and the container elements using flex are:
wrapper: {
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'column'
},
container: {
flex: 0.5
}
The flex value of the container depends on your layout and how much space you want that element to take the screen.

I would recommend using visibility:hidden on the second TextInput. It will retain the spacing, just hide the element.

Related

How to add information pop-up for TextInput in React Native?

I want to achieve something like this in React Native:
I have a TextInput component and I want to put an icon to the right side. The user can click it, then I can display some text in a modal or in a another component.
Is this possible in react native?
return(
<View style={styles.container}>
<TextInput
placeholder="Állat neve"
value={AllatNev}
style={styles.textBox}
onChangeText={(text) => setAllatNev(text)}
/>
</View>
);
}
)
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: color_theme_light.bodyBackground
justifyContent: 'center',
alignItems:'center'
},
textBox:{
borderWidth:2,
borderColor: color_theme_light.textBoxBorder,
margin:15,
borderRadius:10,
padding: 10,
fontFamily:'Quicksand-Medium'
},
});
Yes -- you can position your info button over the TextInput using absolute positioning and a zIndex, for example:
import * as React from 'react';
import { Text, View, StyleSheet, TextInput, TouchableOpacity } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.textBoxParent}>
<TextInput style={styles.textBox} placeholder="Állat neve"/>
<TouchableOpacity style={styles.textBoxButton} onPress={() => {
//launch your modal
}}>
<Text>i</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
textBoxParent: {
justifyContent: 'center'
},
textBox:{
borderWidth:2,
borderColor: 'gray',
margin:15,
borderRadius:10,
padding: 10,
},
textBoxButton: {
position: 'absolute',
right: 20,
zIndex: 100,
width: 20,
height: 20,
borderWidth: 1,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center'
}
});
Working example: https://snack.expo.dev/OFMTc8GHE
Heres a full example of what you want (https://snack.expo.dev/bjzBFuE4W). And below I explain the code.
Fist I made a Modal from react native that takes in modalVisible, setModalVisible, and appears when modalVisible is true.
import * as React from 'react';
import { Text, View, StyleSheet,TextInput ,TouchableOpacity,Modal} from 'react-native';
import { AntDesign } from '#expo/vector-icons';
import { MaterialIcons } from '#expo/vector-icons';
const ModalInfo = ({modalVisible, setModalVisible})=>{
return (
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}>
<View
style={{
width:200,height:200,backgroundColor:"gray",borderWidth:2,
justifyContent:"center",alignItems:"center"
}}
>
<TouchableOpacity onPress={()=>{setModalVisible(false)}}>
<MaterialIcons name="cancel" size={24} color="black" />
</TouchableOpacity>
</View>
</View>
</Modal>
)
}
Next I made a View to wrap around the textInput so I can also add an svg of the info icon. And then set the outside view to have flexDirection:"row", so everything would be ordered the way you wan't.
const TextInputWithModal = ()=>{
const [modalVisible, setModalVisible] = React.useState(false);
const [AllatNev,setAllatNev]= React.useState("");
return (
<View style={styles.textInputContainer}>
<TextInput
placeholder="Állat neve"
value={AllatNev}
style={styles.textBox}
onChangeText={(text) => setAllatNev(text)}
/>
<TouchableOpacity onPress={()=>{setModalVisible(true)}}>
<AntDesign name="infocirlceo" size={24} color="black" />
</TouchableOpacity>
<ModalInfo modalVisible={modalVisible} setModalVisible={setModalVisible}/>
</View>
)
}
export default function App() {
return (
<View style={styles.container}>
<TextInputWithModal/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems:"center",
},
textInputContainer:{
borderRadius:10,
padding: 10,
flexDirection:"row",
margin:15,
borderWidth:2,
},
textBox:{
fontFamily:'Quicksand-Medium',
marginRight:20,
},
});

Showing list empty message at the center of the screen in a FlatList using ListHeaderComponent

I am using React-Native version 0.43.0 which does not support ListEmptyComponent of FlatList. Hence I am using ListHeaderComponent to render a view when the list is empty,
import React, { Component } from 'react';
import { Text, View, StyleSheet,FlatList } from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {
listData: []
}
}
render() {
return (
<View style={styles.container}>
<FlatList
renderItem={() => null}
data={this.state.listData}
ListHeaderComponent={() => (!this.state.listData.length?
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
: null)
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1
},
emptyMessageStyle: {
textAlign: 'center',
//My current hack to center it vertically
//Which does not work as expected
marginTop: '50%',
}
});
As you can see from the image the text is not centered vertically
Any idea how to center it vertically in a FlatList?
I have already tried applying justifyContent, alignItems etc but no use.
This is a link to the snack.expo - https://snack.expo.io/S16dDifZf
Hope this will help you
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
disableVirtualization={false}
data={this.state.data}
renderItem={this.renderItem}
ListEmptyComponent={this.renderEmptyContainer()}
/>
}
/>
Place your UI in the renderEmptyContainer() method and boom, Empty container will show up whenever your list is empty
They fixed ListEmptyComponent in this pr https://github.com/facebook/react-native/pull/18206. But they will ship in 0.56.
UPDATE: Checkout the official doc ListEmptyComponent
You can add a style to the FlatList.
const styles = StyleSheet.create({
container: {
flex:1
},
listStyle: {
justifyContent: 'center'
},
emptyMessageStyle: {
textAlign: 'center',
}
});
render() {
return (
<View style={styles.container}>
<FlatList style={styles.listStyle}
renderItem={() => null}
data={this.state.listData}
ListHeaderComponent={() => (!this.state.listData.length ?
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
: null)}
/>
</View>
);
}
This will center the items in the list, when the list is not empty. You may have to apply another style (when the list is not empty), if you don't prefer the non empty style.
Link to snack.expo
Another option - without changing FlatList style - conditionally rendering FlatList based on this.state.listData.length
render() {
return (
<View style={styles.container}>
{
this.state.listData.length?
(<FlatList
renderItem={() => null}
data={this.state.listData}
/>)
:
(
<View style={styles.emptyListStyle}>
<Text style={styles.emptyMessageStyle}>The list is empty</Text>
</View>
)
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1
},
emptyListStyle: {
flex: 1,
justifyContent: 'center'
},
emptyMessageStyle: {
textAlign: 'center',
}
});
This is the snack.expo
You must combine props ListEmptyComponent with contentContainerStyle={{flex:1}} flex:1 will set the maximal height in the container and will allow you to center vertically. ie:
<FlatList
...
contentContainerStyle={customers.length === 0 && styles.centerEmptySet}
ListEmptyComponent={<EmptySetCustomer />}
/>
Note that you must set a condition to remove flex:1 when list is not empty. To allow scroller.
Hope it will help.
This resolve for me.
<FlatList
contentContainerStyle={{ flexGrow: 1,
justifyContent: "center",
alignItems: "center"}}
disableVirtualization={false}
data={this.state.data}
renderItem={this.renderItem}
ListEmptyComponent={this.renderEmptyContainer()}
/>
}
/>
As a temporary workaround you can conditionally set a style to the contentContainer to center only the empty set like this
<FlatList
contentContainerStyle={customers.length === 0 && styles.centerEmptySet}
data={customers}
renderItem={({ item, index }) => (
/// Your item here
)}
keyExtractor={(item, index) => {
return String(index);
}}
ListEmptyComponent={<EmptySetCustomer />}
/>
And styles like this
centerEmptySet: { justifyContent: 'center', alignItems: 'center', height: '100%' }
Then in 2-3 weeks we can update to 0.56 and remove the workaround
<FlatList
keyExtractor={(item) => item.id}
data={flatListItems}
ListEmptyComponent={<View style= {styles.EmptytextHeader}><Text style={styles.EmptyMassage}>No data found</Text></View>}
renderItem={({ item }) => {
return <View><Text>add Your Data</Text></View>
/>
}}
/>
const styles = StyleSheet.create({
EmptytextHeader: {
flex:1,
justifyContent:'center',
alignItems:'center'
},
EmptyMassage: {
color:'red',
fontWeight: '700',
fontSize: 16,
fontStyle: 'normal',
},
});
its working

How do I overlay ActivityIndicator in react-native?

I have a View with few form elements and a button (TouchableHighlight). On clicking the button, an Activity Indicator should be shown as an overlay to the existing view. The Activity Indicator should be centered within the page and the existing view should be slightly blurred to indicate overlay. I tried different options but could not get it to work.
render() {
const { username, password } = this.state;
return (
<View style={styles.container}>
<View style={styles.group}>
<Text style={styles.text}>Username:</Text>
<TextInput
style={styles.input}
onChangeText={this.handleUserNameChange.bind(this)}
value={username}
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.group}>
<Text style={styles.text}>Password:</Text>
<TextInput
style={styles.input}
secureTextEntry={true}
onChangeText={this.handlePasswordChange.bind(this)}
value={password}
underlineColorAndroid="transparent"
/>
</View>
<TouchableHighlight
style={styles.button}
onPress={this.handleLogin.bind(this)}>
<Text style={styles.buttonText}>Logon</Text>
</TouchableHighlight>
</View>
);
}
Existing styles:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#F5FCFF',
marginTop: 60
},
group: {
alignItems: 'flex-start',
padding: 10
},
input: {
width: 150,
padding: 2,
paddingLeft: 5,
borderColor: 'gray',
borderWidth: 1
},
text: {
padding: 0
},
button: {
width: 150,
backgroundColor: '#2299F2',
padding: 15,
marginTop: 20,
borderRadius: 5
},
buttonText: {
textAlign: 'center',
color: '#fff',
fontSize: 24
},
});
I need to an ActivityIndicator to the above View, overlay the view, and center the ActivityIndicator.
For this to work, you'd need to absolute position it, and render it after the elements that should be underneath the overlay:
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
}
Then simply compose it into the render method conditionally, based on a loading state. I am going to assume this.handleLogin sets some sort of loading state already.
Make sure it's rendered last so it takes precedence.
...
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator size='large' />
</View>
}
Here is a complete example using create react native app.
import React from 'react';
import {StyleSheet, ActivityIndicator, View} from "react-native";
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {}
render() {
return (
<View
style={{flex: 1}}
>
//Add other content here
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator/>
</View>
}
</View>
);
}
}
showLoading() {
this.setState({loading: true})
}
hideLoading() {
this.setState({loading: false})
}
const styles = StyleSheet.create({
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.5,
backgroundColor: 'black',
justifyContent: 'center',
alignItems: 'center'
}
})
You can use StyleSheet.absoluteFill to shorten code.
Add this to your render:
<View style={styles.container}>
//... other code here
{this.state.loading && <View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator />
</View>}
</View>
Improvement:
You can also create a Loading component:
Loading.js
import React from 'react';
import {View, ActivityIndicator, StyleSheet} from 'react-native';
export const Loading = ({theme = 'white', size = 'large'}) => {
const color = theme === 'white' ? '#00bdcd' : '#fff';
return (
<View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator size={size} color={color} />
</View>
);
};
Then use it anywhere you want
<View style={styles.container}>
//... other code here
// remember to import Loading component
{this.state.loading && <Loading />}
</View>
You can build a nice overlay using the activity indicator component by also leveraging the modal capabilities like Sanaur suggests.
For example you can use the below functional component. You can control it's visibility through the show prop that you can tie to a state in your screen.
An example that you can adapt to your needs.
const ModalActivityIndicator = props => {
const {
show = false,
color = "black",
backgroundColor = "white",
dimLights = 0.6,
loadingMessage = "Doing stuff ..."
} = props;
return (
<Modal transparent={true} animationType="none" visible={show}>
<View
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: `rgba(0,0,0,${dimLights})`
}}
>
<View
style={{
padding: 13,
backgroundColor: `${backgroundColor}`,
borderRadius: 13
}}
>
<ActivityIndicator animating={show} color={color} size="large" />
<Text style={{ color: `${color}` }}>{loadingMessage}</Text>
</View>
</View>
</Modal>
);
};
and in your screen, in the render's return, just add it there as a child (please ignore the rest of the code, I put it there for context).
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={{ padding: 13, flex: 1}}>
<ModalActivityIndicator show={screenIsWaiting} />
<View
style={{
where screenIsWaiting is just a state, for example
const [screenIsWaiting, setScreenIsWaiting] = useState(false);
To test it you can add a button somewhere,
<Button
title="TestButton"
onPress={async () => {
setScreenIsWaiting(true);
await sleep(5000);
setScreenIsWaiting(false);
...
}}
/>
where sleep is a function defined as
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
I found the sleep() idea on stackoverflow on another post.
You can of course also define the
<ModalActivityIndicator show={screenIsWaiting} ... />
only once in your App's root component and trigger it's display and props via a global state container like redux.
There is a library available for this react-native-loading-spinner-overlay.
You can simply install it using
npm install react-native-loading-spinner-overlay --save
and can import into your project using
import Spinner from 'react-native-loading-spinner-overlay';
Here is how to use it
<Spinner
//visibility of Overlay Loading Spinner
visible={this.state.loading}
//Text with the Spinner
textContent={'Loading...'}
//Text style of the Spinner Text
textStyle={styles.spinnerTextStyle}
/>
STEP 1:
Create the component for the spinner:
export const OverlaySpinner = () => {
return (
<View style={styles.spinnerView}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
};
STEP 2:
Create the style for the spinner view (using zIndex is very important to make sure the view is over everything on the screen):
spinnerView: {
position: "absolute",
zIndex: 1,
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#F5FCFF88",
},
STEP 3:
Make the initial state for the spinning component:
const [showSpinner, setshowSpinner] = useState(true);
STEP 4:
Use the component and don't forget to import it (don't forget to dismiss the keyboard on submit)
{showSpinner && <OverlaySpinner />}
I suppose you should use Modal to overlay activity indicator. Following is an example:
<Modal
transparent={true}
animationType={'none'}
visible={loading}
onRequestClose={() => {console.log('close modal')}}>
<View style={styles.modalBackground}>
<View style={styles.activityIndicatorWrapper}>
<ActivityIndicator
animating={loading} />
</View>
</View>
</Modal>
Add in view of loading
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
set in View of Activity Indicator
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
Here my code for a functional component for anyone looking to achieve this with nativebase as design system. useColorScheme is another hook I use for detecting dark mode.
import { Flex, Spinner } from "native-base"
import React from "react"
import useColorScheme from "../../hooks/useColorScheme"
export default function Loading() {
const colorScheme = useColorScheme()
return (
<Flex
position="absolute"
alignItems="center"
justifyContent="center"
top={0}
left={0}
right={0}
bottom={0}
backgroundColor={colorScheme === "dark" ? "coolBlack.500" : "white"}
>
<Spinner size="lg" color={colorScheme === "dark" ? "white" : "coolBlack.500"} />
</Flex>
)
}

Trying to create two columns in react-native

I am trying to create a two column grid using flex. One column will be used to display a word or phrase and the second column will be used to translate the first column. Here is a link: http://imgur.com/nZGo8pb to give you a visual idea on what I am trying to achieve.
I am unable to get two columns side by side. I am only able to have my words appear on top of each other. This is best attempt. A huge failure.http://imgur.com/a/ICApr
My code is:
nent} from 'react';
import { Text, View,StyleSheet,Image,TextInput,ListView} from 'react-native';
class AddWords extends Component{
state = {words:['iku','konkai','kaikan'],
word:'',
EnglishWords:['go','this time','next time']
}
renderList(tasks){
return(
tasks.map((task) =>{
return(
<View key={task} style={styles.item}>
<Text>
{task}
</Text>
<Text>
</Text>
</View>
)
})
)
}
renderEnglishWords(english){
return(
english.map((english) =>{
return(
<View key={english} style={styles.item2}>
<Text>
{english}
</Text>
<Text>
</Text>
</View>
)
})
)
}
addWord(){
let words = this.state.words.concat([this.state.word]);
this.setState({words})
}
render(){
return(
<View style={styles.container}>
<TextInput
style={styles.input}
onChangeText={(word) => {
this.setState({word})
}}
onEndEditing={()=>this.addWord()}
/>
<View style={styles.wordContainer}>
{this.renderList(this.state.words)}
{this.renderEnglishWords(this.state.EnglishWords)}
<View style={styles.item2}>
</View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container:{
flex:1,
borderWidth:3,
borderColor:'green',
flexDirection:'column',
paddingTop:10
},
wordContainer:{
flexDirection: 'column',
borderColor:'blue',
borderWidth:2
},
input:{
height:60,
borderWidth:1,
borderRadius:5,
borderColor:'black',
textAlign:'center',
margin:10,
paddingTop:20,
paddingBottom:10
},
item:{
borderColor:'red',
borderWidth:2
},
item2:{
borderColor:'black',
borderWidth:2,
flexDirection:'column',
}
})
export default AddWords;
Any help will be greatly appreciated.
Thanks.
You need to wrap both inner containers in another <View> with the following style:
<View style={styles.container}>
<TextInput
style={styles.input}
onChangeText={(word) => {
this.setState({ word })
}}
onEndEditing={this.addWord}
/>
<View style={{ flexDirection: 'row', flex: 1 }}>
<View style={styles.wordContainer}>
...
</View>
<View style={styles.item2}>
...
</View>
</View>
</View>
It's because the flexDirection in styles.wordContainer is set to 'column', it should be set to 'row'.
Check out this link on flex-direction examples.

How to add a button in React Native?

I´m confused with this whole "no CSS" thing, but I understand why it's beneficial. All I want to do is place a button in the middle of the screen but I don't understand how styling works in React yet. This is my code:
var tapSpeed = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Tap me as fast as you can!
</Text>
<View style={styles.button}>
!
</View>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFCCCC'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10
},
button: {
textAlign: 'center',
color: '#ffffff',
marginBottom: 7,
border: 1px solid blue,
borderRadius: 2px
}
});
Update: use built-in Button component.
Deprecated:
Wrap your View into TouchableHighlight for iOS and TouchableNativeFeedback for Android.
var {
Platform,
TouchableHighlight,
TouchableNativeFeedback
} = React;
var tapSpeed = React.createClass({
buttonClicked: function() {
console.log('button clicked');
},
render: function() {
var TouchableElement = TouchableHighlight;
if (Platform.OS === 'android') {
TouchableElement = TouchableNativeFeedback;
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Tap me as fast as you can!
</Text>
<TouchableElement
style={styles.button}
onPress={this.buttonClicked.bind(this)}>
<View>
<Text style={styles.buttonText}>Button!</Text>
</View>
</TouchableElement>
</View>
);
}
});
You can use built in react-native Button element.
import React, { Component } from 'react';
import { StyleSheet, View, Button, Alert, AppRegistry } from 'react-native';
class MainApp extends Component {
_onPress() {
Alert.alert('on Press!');
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button onPress={this._onPress} title="Hello" color="#FFFFFF" accessibilityLabel="Tap on Me"/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFFFFF'
},
buttonContainer: {
backgroundColor: '#2E9298',
borderRadius: 10,
padding: 10,
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 3
},
shadowRadius: 10,
shadowOpacity: 0.25
}
})
AppRegistry.registerComponent('MainApp', () => MainApp);
Read More Here.
The react-native-button package provides a button that is styled like a native button. Install it with npm install react-native-button and use it in your component like this:
var Button = require('react-native-button');
var ExampleComponent = React.createClass({
render() {
return (
<Button
style={{borderWidth: 1, borderColor: 'blue'}}
onPress={this._handlePress}>
Press Me!
</Button>
);
},
_handlePress(event) {
console.log('Pressed!');
},
});
You have two options to achieve a touchable component/button to handle user's events.
One is to use the built in Button Component. Check the docs here http://facebook.github.io/react-native/docs/button.html
Two use either TouchableHighlight or TouchableNativeFeedback or TouchableOpacity or TouchableWithoutFeedback. Think of this as a way for you to convert different areas of your app to tappable(clickable) or a way for you to create a custom button.
Each component here is different based on how it behaves once it's tapped by the user. Check the docs for more details. http://facebook.github.io/react-native/docs/touchablewithoutfeedback.html etc.
Concerning styling in react native you will need to understand flexbox layout. Check this css flexbox article all rules are applicable to react-native https://css-tricks.com/snippets/css/a-guide-to-flexbox/ except that you will have to capitalize the rules e.g align-content to alignContent
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
Please check react-native doc's regarding the buttons
You have more than one way to add button in your application and styling it
You can use Button tag and it's have only one way styling by color attribute, it will appearing in IOS different than Android, or by putting button in view tag with style
<View style={style.buttonViewStyle}>
<Button title="Facebook" color="blue" onPress={this.onFacebookPress} />
</View>
And check the TouchableOpacity and TouchableNativeFeedback tags
And take a lock on below link for more options to add custom buttons in your app
https://js.coach/react-native/react-native-action-button?search=button
export default class Login extends React.Component {
barcodeAction = () => {
this.props.navigation.navigate('BarCodeScanner')
}
cleverTapAction = () => {
this.props.navigation.navigate('CleverTapApp')
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
color="#841584"
/>
</View>
<View style={styles.alternativeLayoutButtonContainer}>
<Button
onPress={this._onPressButton}
title="This looks great!"
/>
<Button
onPress={this._onPressButton}
title="OK!"
color="#841584"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer: {
margin: 20
},
alternativeLayoutButtonContainer: {
margin: 20,
flexDirection: 'row',
justifyContent: 'space-between'
}
});
The Button element from react-native package does not provide built in styling feature. Ex. The "title" props will be in upper case by default. Hence, I've used an another package react-native-elements that provides nice features for Button element along with different styling options.
You can refer more details on Button from react-native-elements
import React, { Component } from 'react';
import { StyleSheet, View, TouchableOpacity, Text} from 'react-native';
var tapSpeed = React.createClass({
render: function() {
return (
<View style={styles.container}>
<TouchableOpacity>
<Text style={styles.welcome}>
Tap me as fast as you can!
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}>
<Text>!</Text>
</TouchableOpacity>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
backgroundColor: '#FFCCCC'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
alignSelf: 'center'
},
button: {
justifyContent: 'center',
alignItems: 'center',
marginBottom: 7,
border: 1px solid blue,
borderRadius: 2px
}
});

Categories

Resources