Disable TouchableOpacity for nested View - react-native

I've a touchable opacity, and I have a few views inside it. I have one specific view that I don't want for it to be clickable. How can I achieve this?

The specific view that you don't want for it to be clickable should be "TouchableOpacity" but have activeOpacity={1} . In this way parent TouchableOpacity will not work and activeOpacity={1} will make it like disable
Complete code
import React, { Component } from "react";
import { TouchableOpacity, View, Text } from "react-native";
export default class App extends Component {
render() {
return (
<View style={{ flex: 1, margin: 50 }}>
<TouchableOpacity
style={{ backgroundColor: "red", width: 250, height: 250 }}
>
<TouchableOpacity
style={{
backgroundColor: "green",
width: 100,
height: 100,
margin: 20,
alignItems: "center",
justifyContent: "center"
}}
activeOpacity={1}
>
<Text>No Click Area</Text>
</TouchableOpacity>
</TouchableOpacity>
</View>
);
}
}
App Preview

Go in that view and add a prop => pointerEvents:none
<View pointerEvents="none" />
Please refer here

I don't know what conditions you're talking about, but if you want to do what you want, you can use the status value. To deactivate a button when displaying a screen, change the status value when rendering the screen, or change it when you press a button. The examples are attached together.
Example
import * as React from 'react';
import { Text, View, StyleSheet,TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
export default class App extends React.Component {
constructor(props){
super(props);
this.state={
disabled: false
}
}
componentDidMount(){
this.setState({ disabled: true})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Text>
<TouchableOpacity style={{width:"100%",height:20,alignItems:"center",backgroundColor:"blue"}} onPress={() => alert("touch")} disabled={this.state.disabled}>
<Text>Touch </Text>
</TouchableOpacity>
<TouchableOpacity style={{width:"100%",height:20,alignItems:"center",backgroundColor:"red"}} onPress={() => this.setState({disabled:true})}>
<Text>disabled</Text>
</TouchableOpacity>
</View>
);
}
}

Another way you could do it is to wrap you View which you don't want to be clickable with TouchableWithoutFeedback.
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, justifyContent: 'center'}}>
<TouchableOpacity style={{backgroundColor: "blue", width: 300, height: 300}}>
<TouchableWithoutFeedback>
<View style={{backgroundColor: "yellow", width: 100, height: 100}}>
<Text>Hello</Text>
</View>
</TouchableWithoutFeedback>
</TouchableOpacity>
</View>
);
}
}

As #AnaGard suggested, the key to having a press free view inside a pressable container is to make a pressable inner view without an onPress value.
Better than using TouchableOpacity is using the Pressable component, which the ReactNative's documentation suggests is more future-proof.
Therefore, an updated answer to this question might be as follows:
<View>
<Pressable
style={{ width: 500, height: 250 }}
onPress={() => onClose()}
>
<Pressable style={{ height: 100, width: 200 }}>
<View>
<Text>Your content here</Text>
</View>
</Pressable>
</Pressable>
</View>
Some references:
Pressable
TouchableOpacity

Related

How to make curve design in react native?

I'm creating a react native app and I need to create a curved screen design. How to create a curve design like the below screen.
This is what I tried here,
My sample codes,
import React from 'react';
import {
StyleSheet,
Text,
View,
StatusBar,
} from 'react-native';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from 'react-native-responsive-screen';
export default class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<StatusBar hidden={true} />
<View style={styles.container1}>
<Text style={styles.name}>Container1</Text>
</View>
<View style={styles.container2}>
<Text style={styles.name}>Container1</Text>
</View>
<View style={styles.container3}>
<Text style={styles.name}>Container1</Text>
</View>
<View style={styles.container4}>
<Text style={styles.name}>Container1</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
container1: {
backgroundColor: '#3d06d6',
height: hp('25%'),
padding: 10,
borderBottomLeftRadius:100,
},
container2: {
backgroundColor: '#0cad95',
height: hp('25%'),
padding: 10,
borderBottomLeftRadius:100,
},
container3: {
backgroundColor: '#d6a606',
height: hp('25%'),
padding: 10,
borderBottomLeftRadius:100,
},
container4: {
backgroundColor: '#06bad6',
height: hp('25%'),
padding: 10,
borderBottomLeftRadius:100,
},
});
I want to curve my container edges like the first picture. I am able to make curves of the bottom edges. And How can I make curve designs like the first image? and also how can I add some animations into the container when I touch the container to open another screen? Is there any way to do this design using any style with "borderRadius" or any other way? And I don't want to use any library like react-native-svg.
If you need a Linear Gradient as the background. Just giving the color of the next box will not be the best option.
Assume "value" as the border-radius. ie the curve
Give a marginTop and paddingTop for each container.
marginTop : -value,
paddingTop : value,
Also assign zIndex in decending order for each container.
You can set zIndex with respect to the index, if you are looping through an array.
Result
Sample code
import React from 'react';
import {View, StyleSheet, Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
const data = ['', '', ''];
const App = () => {
return (
<View style={styles.container}>
{data.map((item, index) => (
<View style={[styles.item, {zIndex: data.length - index}]}> // setting zIndex here
<LinearGradient
style={StyleSheet.absoluteFill}
colors={['#4c669f', '#3b5998', '#192f6a']}
/>
</View>
))}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
zIndex: 1,
},
item: {
height: 250,
borderBottomLeftRadius: 100, // logic goes here
marginTop: -100, // move container
paddingTop: 100, // move inner item down
overflow: 'hidden',
},
});
export default App;
You can simply wrap your view inside a normal view and set the background colour of the next box which will give the output you need.
<View style={{ backgroundColor: '#0cad95' }}>
<View style={styles.container1}>
<Text style={styles.name}>Container1</Text>
</View>
</View>
<View style={{ backgroundColor: '#d6a606' }}>
<View style={styles.container2}>
<Text style={styles.name}>Container1</Text>
</View>
</View>

How to fixed element in react native

I have a flatlist that shows my restaurant foods. and I have a buy basket that shows the count and total cost of foods. Now I want to know how can I fixed the position of the basket buy on the flat list.
Note: The buy basket on the flat list is a little icon that shows the count and total cost of foods.
Thanks advance.
If you are looking for Floating Action Button like a solution with Flatlist like below example image, find the full code here.
Example Image
<FlatList
data={data}
renderItem={({ item }) => <View style={styles.list}>
<Text>Name : {item.name}</Text>
<Text>Age : {item.age}</Text>
</View>}
/>
<TouchableOpacity onPress={() => alert('FAB clicked')}
style={{
position: 'absolute',
width: 56,
height: 56,
alignItems: 'center',
justifyContent: 'center',
right: 20,
bottom: 20,
backgroundColor: '#03A9F4',
borderRadius: 30,
elevation: 8
}}>
<Text style={{ fontSize: 40,color: 'white'}}>+</Text>
</TouchableOpacity>
You should do something like this:
//MyComponent.js
import { FlatList, View, ScrollView } from 'react-native';
export default class MyComponent extends Component {
renderFlatlist() {
return <FlatList data={...} />;
}
renderBasket() {
return (
<View>
//Your basket
</View>
);
}
render() {
return (
<View>
<ScrollView>
{this.renderFlatlist()}
</ScrollView>
<View>
{this.renderBasket()}
</View>
</View>
)
}
}

React Native: Align two TextInputs side by side

I am just starting out with React Native and I am developing an app using RN ... I am bit stuck here ... I have a form in one of the app's component that have couple of TextInputs aligned side by side like in the image below
Here is the code that I have written trying to achieve the above design.
import React, {Component} from 'react';
import {View, Text, StyleSheet, TextInput, TouchableHighlight} from 'react-native';
export default class AddItems extends Component {
onAdd() {
alert('Hello');
}
render() {
return (
<View style={addItemStyles.wrapper}>
<View>
<Text>Item to give cash credit for:</Text>
<View>
<View>
<TextInput placeholder="Test" style={{justifyContent: 'flex-start',}} />
</View>
<View>
<TextInput placeholder="Test" style={{justifyContent: 'flex-end',}} />
</View>
</View>
</View>
</View>
);
}
}
const addItemStyles = StyleSheet.create({
wrapper: {
padding: 10,
backgroundColor: '#FFFFFF'
},
inputLabels: {
fontSize: 16,
color: '#000000',
marginBottom: 7,
},
inputField: {
backgroundColor: '#EEEEEE',
padding: 10,
color: '#505050',
height: 50
},
inputWrapper: {
paddingBottom: 20,
},
saveBtn: {
backgroundColor: '#003E7D',
alignItems: 'center',
padding: 12,
},
saveBtnText: {
color: '#FFFFFF',
fontSize: 18,
}
});
But instead I am getting the view like this.
I know this could be a minor thing but as I said above that I am just starting with React Native so you can consider me as a noob ... Thanks in advance for your help. Looking forward to your answers.
use "flexDirection" in style
render() {
return (
<View style={addItemStyles.wrapper}>
<View>
<Text>Item to give cash credit for:</Text>
<View style={{flexDirection:"row"}}>
<View style={{flex:1}}>
<TextInput placeholder="Test" style={{justifyContent: 'flex-start',}} />
</View>
<View style={{flex:1}}>
<TextInput placeholder="Test" style={{justifyContent: 'flex-end',}} />
</View>
</View>
</View>
</View>
);
}

Vertical text in react native is cut by it's original height (using transform)

I have the following code in which I would like the black boxed text to be placed vertically, either centered or aligned to the top, and be cut by the end of the corresponding text view (sample text).
It seems like even though the text is transformed, it still measures its original height and thus shows only the first letter with ...
adding width:50 to the transformed view, will show better results, but the number of lines in the sample text is changing (and also the font sizes).
this is the result I'm getting:
And this is the required result (using paint.net ;)):
Does anyone have an idea how to do it?
Thanks!
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
class SideComponent extends Component{
render(){
return (
<View style={{flex:1, alignItems:'center', justifyContent:'center', borderColor:'black', borderWidth:0.5, width:20,}}>
<View style={{transform: [{ rotate: '90deg'}]}}>
<Text numberOfLines={1} style={{borderColor:'blue'}}>{this.props.text}</Text>
</View>
</View>
)
}
}
class LineComponent extends Component{
render(){
return (
<View style={{flex:1}}>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
</View>
)
}
}
export default class App extends Component{
render() {
return (
<View style={styles.container}>
<View style={{flexDirection:'row'}}>
<SideComponent text="Short"/>
<LineComponent/>
</View>
<View style={{flexDirection:'row'}}>
<SideComponent text="LongTextLong" style={{}}/>
<LineComponent/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
flexDirection: 'column',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
I tried something like this for vertical transformation:
<View style={{flexDirection:'row'}}>
<View style={{flex:0.1 }}>
<View style={{left:-130,width:300,height:20,alignItems:'flex-start',justifyContent:'flex-start',transform: [{ rotate: '270deg'}]}}>
<Text numberOfLines={1} style={[AppStyles.regularFontText,{fontSize:12,color:'#8160e5'}]}>Number of Users</Text>
</View>
</View>
<View style={{flex:0.9}}>
<BarChart
style={{height:200,width:width-100[enter image description here][1]}}
data={this.state.line_data}
chartDescription={{ text: '' }}
xAxis={this.state.xAxis}
animation={{durationX: 2000}}
legend={this.state.line_legend}
gridBackgroundColor={processColor('#ffffff')}
drawBarShadow={false}
drawValueAboveBar={true}
drawHighlightArrow={true}
onSelect={this.handleSelect.bind(this)}
highlights={this.state.highlights}
onChange={(event) => console.log(event.nativeEvent)}
/>
</View>
</View>

Unexpected token at line with <image > tag in React Native

<Image source={require('./cat.jpeg')}/>
I have this line inside the render function, and when I run the code, I get an error Unexpected token at this line.How to resolve this?
The image cat.jpeg is in the same folder as the current component.
Here is the full code:
'use strict'
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
View,
Image
} from 'react-native';
import { Actions } from 'react-native-router-flux';
export default class HomeScreen extends Component{
render() {
return (
<View style={styles.container}>
<View style={styles.rowcontainer}>
// <Image style={{width: 50, height:50}}
// source={{uri: 'https://facebook.github.io/react/img/logo_small.png'}}/>
<Image source={require('./cat.jpeg')}/>
<Text onPress={Actions.MarkAttendance}style={styles.welcome}>
Mark Attendance
</Text>
<Text onPress={Actions.AttendanceDetails}style={styles.welcome}>
View Attendance
</Text>
</View>
<View style={styles.rowcontainer}>
<Text onPress={Actions.Test}style={styles.welcome}>
Test
</Text>
<Text onPress={Actions.NewActivation}style={styles.welcome}>
New Activation
</Text>
</View>
<View style={styles.rowcontainer}>
<Text onPress={Actions.PendingAttendance}style={styles.welcome}>
Pending Attendance
</Text>
<Text onPress={Actions.Checkout}style={styles.welcome}>
Checkout
</Text>
</View>
<View style={styles.rowcontainer}>
<Text onPress={Actions.Settings}style={styles.welcome}>
Settings
</Text>
<Text style={styles.welcome}>
Logout
</Text>
</View>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
marginTop:50,
backgroundColor: '#FFFFFF',
},
rowcontainer:{
alignItems:'stretch',
flexDirection:'row',
justifyContent:'space-between',
margin: 10,
},
welcome:{
fontSize:15,
}
});
You can't use // to comment out pieces of code inside of your render function while using the HTML-like syntax.
Instead try wrapping whatever you're trying to comment out inside of {} and using the javascript blockcomments there.
e.g.
{/*
<Image
source=.../>
*/}