React Native, TouchableOpacity wrapping floating button get nothing - android

I'm creating a simple action button (floating button)
This is working :
<View style={{
width: this.props.size,
height: this.props.size,
borderRadius: this.props.size / 2,
backgroundColor: '#ee6e73',
position: 'absolute',
bottom: 10,
right: 10,
flexDirection:'row'
}}>
<Text>
+
</Text>
</View>
This is not :
<TouchableOpacity
onPress={()=>{
}} >
<View style={{
width: this.props.size,
height: this.props.size,
borderRadius: this.props.size / 2,
backgroundColor: '#ee6e73',
position: 'absolute',
bottom: 10,
right: 10,
flexDirection:'row'
}}>
<Text>
+
</Text>
</View>
</TouchableOpacity>
Just wrap with TouchableOpacity then my button not show up without any errors.
React 0.1.7, Android
Then I try move styling from View to TouchableOpacity, It's work
<TouchableOpacity
onPress={()=>{
}}
style={{
width: this.props.size,
height: this.props.size,
position: 'absolute',
borderRadius: this.props.size / 2,
backgroundColor: '#ee6e73',
bottom: 10,
right: 10,
}}>
<Text>
+
</Text>
</TouchableOpacity>
Can any one explain me why?
React Native docs said
[https://facebook.github.io/react-native/docs/touchableopacity.html][1]
A wrapper for making views respond properly to touches.
This is done without actually changing the view hierarchy,
and in general is easy to add to an app without weird side-effects.
This mean I wrap my original view and it would work as I expected, But it's not.

From my experience, TouchableOpacity does not work well with absolute positioning. Perhaps if you remove that, the onPress will work again.
Also please note that it is EXTREMELY important what element you render first and what you render last.
For example, if you do:
<View>
<TouchableOpacity style={{position:'absolute'}} onPress={()=>
{console.log("It works or not?")}}>
</TouchableOpacity>
<Text style={styles.aStyle}>
Some text bla bla......
</Text>
</View>
There is a pretty good chance that the Text will be rendered on top of the TouchableOpacity, therefore you won't be able to get the onPress working.
Then since the position is absolute, all you have to do is render it as the last child of the View:
<View>
<Text style={styles.aStyle}>
Some text bla bla
</Text>
<TouchableOpacity style={{position:'absolute'}} onPress={()=>
{console.log("It works or not?")}}>
</TouchableOpacity>
</View>

I know this is old but I had this issue and nothing above worked until adding flex: 1 to my TouchableOpacity.

TouchableOpacity does not assume the style of the view it is the parent of. You need provide it style information.

Incase anyone else stumbles across this, and none of these suggestions work my fix was to instead import TouchableOpacity from react-native instead of react-native-gesture-handler
So
import { TouchableOpacity } from "react-native";
Instead of
import { TouchableOpacity } from "react-native-gesture-handler";

I had a similar issue after a lot of debugging I found out that negative margin was the problem.
Beware of negative margin when using TouchableOpacity
Debugging step:
Remove all the styling
Create fresh component without styling
Make sure it is working without styling
Then state adding your styling

Related

How to handle large image in modal (react native android)

I have a modal that a link is passed to for image pinch zoom and it works perfectly on iOS, but apparently android has a limitation with the fresco plugin. I get an error Pool hard cap violation? Hard cap = 201326592 Used size = 191114208 Free size = 0 Request size = 10933048 error. This results in nothing showing.
How does one handle images inside a modal that a user can zoom/pan with? It works perfectly on iOS - It's just android that's having this issue. I don't want to really resize it because the user should be able to zoom, so we want it to be larger than the view. Documentation doesn't cover this at all.
Code (for illustration purposes):
<Modal ref={modalRef} supportedOrientations={['landscape', 'portrait']} animationType='fade' visible={!!modalImage} style={{...StyleSheet.absoluteFillObject}}>
<StatusBar backgroundColor={"#000"} />
<View style={{flex: 1, backgroundColor: '#FFF', position: 'relative'}}>
<TouchableOpacity hitSlop={{ top: 20, bottom: 20, left: 20, right: 20}} style={{position: 'absolute', top: '5%', right: '5%', width: 20, height: 20, zIndex: 999}} onPress={() => setModalImage(null)}>
<Image style={{width: '100%', height: '100%'}} source={require('../assets/icons/Miscellaneous/Close/close-dark-mode.png')} />
</TouchableOpacity>
<ReactNativeZoomableView
ref={zoomableRef}
style={{width: '100%', height: '100%', backgroundColor: '#000'}}
maxZoom={3}
minZoom={1}
zoomStep={3}
onShiftingBefore={_onShiftBefore}
onShiftingAfter={_onShiftAfter}
>
<Image onError={(e) => console.log('error', e.nativeEvent.error)} style={{width: '100%', height: '100%'}} resizeMode='contain' resizeMethod='resize' source={{ uri: `https://website.com${HtmlTextParser(modalImage ?? '')}` }} />
</ReactNativeZoomableView>
</View>
</Modal>
I'm using a zoomable view inside a modal in the same manner that you explained but never ran into this issue, the difference I found between our implementations is that I have those props specified in zoomable view and not inside the image style.
contentWidth={}
contentHeight={}
I'm not sure if you're using the deprecated one, if so I'd suggest that you try this instead
https://github.com/openspacelabs/react-native-zoomable-view
let me know if those suggestions helped.

How to set borderRadius on a react-native modal?

I have a react-native Modal, I would like to render it with rounded corners like this:
but if I define it like this:
<Modal
style={{
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
overflow: 'hidden',
}}
nothing happens (at least on Android). I also tried to wrap the Modal with a View with the same style but with no more success.
What am I doing wrong?
The solution is to put a View inside the Modal (right after its declaration) with this style:
<Modal>
<View
style={{
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
overflow: 'hidden',
}}
>
</Modal>

React native Modal, avoid resizing View when keyboard is opened (Android)

I'm using a react-native Modal, which contains a View.
The View has some TextInput elements. When the keyboard pops up, the View elements all collapse to fit into the remaining space, but I don't want the View to change at all.
This does not happen for IOS. And also, it does not happen in non-modal Views for Android within the same app.
I have windowSoftInputMode="adjustPan" set in my android Manifest, but it doesn't seem to be applied on the Modal.
return(
<ImageBackground source={require('./../images/IMG1.png')}
style={{flex: 1}} imageStyle={{resizeMode: 'cover'}}>
<View style={{flex: 1}}>
(...)
<Modal visible={this.state.modalVisible} animationType={'slide'}
presentationStyle={'fullScreen'}
onRequestClose={() => this.closeModal()}>
<ImageBackground source={require('./../images/IMG2.png')}
style={{flex: 1}} imageStyle={{resizeMode: 'cover'}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={{flex:1}}>
(...)
<View style={{flex:0.9, alignItems:'center', justifyContent: 'center',
flexDirection: 'row'}}>
<TextInput style={MyStyle.textInput}
onChangeText={(myTitle) => this.setState({myTitle})}
placeholder='Title'
/>
</View>
As a workaround, I ended up using a fixed height value for the Modal’s child View instead of flex. (Got it using Dimensions height).
It seems to work as I expected.
Seems like you need to apply statusBarTranslucent={true} prop for the Modal to make the modal content not to resize and the keyboard to pan over the modal content.
My workaround: I used the following style for the child of the modal.
container: {
left: 50,
position: "absolute",
right: 50,
top: 50
}

Has anyone found a workaround for nesting views in React Native on Android?

Hey I was wondering if there was some kind of workaround for nesting views on React Native on android, it seems that things like
class BlueIsCool extends Component {
render() {
return (
<Text>
There is a blue square
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
in between my text.
</Text>
);
}
}
is not possible on Android. Is there any way to do something like this on Android using React Native?
You may simply do
<View>
<Text>
There is a blue square
</Text>
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
<Text>
in between my text.
</Text>
</View>

React Native Android - how do i *stop* <View>'s from resizing automatically when inside a Modal?

version of RN is 0.41.2
does anyone know how to stop View's that use flexbox for sizing, from automatically "shrinking" their height if a TextInput element is used in one of the Views? It's probably easier to illustrate by example, and to be clear, you can see that these are View's nested inside a <Modal>.
Here is the view when no keyboard is open. Same on both.
Here's what happens when TextInput has the focus. I dont want these views to adjust as they have, above the keyboard. I want the yellow and blue colored View's to remain 'full size' - exactly as illustrated in the iOS screenshot.
This same code, on iOS, does not move/adjust the View's (above the keyboard). That's the behavior I want on Android too.
Here is the sample render method code. It's just a standard template RN project with a change to the render method to test this out.
I tried inserting android:windowSoftInputMode="adjustNothing" into AndroidManifest.xml but had no effect. I'm sure it's just a prop or other manifest setting. Hoping someone can let me know?
render() {
return (
<View style={styles.container}>
<Modal
animationType={'slide'}
transparent={false}
onRequestClose={() => console.log('sd')}
>
<View style={{flex:1, backgroundColor: 'lightgrey'}}>
<View style={{
//height:300,
flex: 1,
backgroundColor: 'yellow',
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={{
margin: 10,
//height:100,
width: 200,
justifyContent: 'center',
backgroundColor: 'green'}}>
<TextInput style={{height: 40, backgroundColor: 'orange'}} />
</View>
</View>
<View style={{
//height:200,
flex: 1,
backgroundColor: 'blue',
}}>
</View>
</View>
</Modal>
</View>
);
}
Did you try wrapping all of the contents within a ScrollView and then a child KeyboardAvoidingView?
I had exactly the same problem, and instead of adding ScrollView everywhere I just made a little change in AndroidManifest.xml:
instead of: android:windowSoftInputMode="adjustResize"
i wrote: android:windowSoftInputMode="adjustPan"
Worked like a charm for me

Categories

Resources