Can I the View of images be display in React-Native? - react-native

I have just stared react-native.
I got a strange situation.
In simulator's iOS, it's well. (like below)
But, In device's Android, it's not.
I set the margin to minus but it's cut in Android.
And images are just all black.
Entire code.
import React from 'react';
import {
ActivityIndicator,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
Dimensions
} from 'react-native';
import Image from 'react-native-scalable-image';
import resolveAssetSource from 'resolveAssetSource';
// import FastImage from 'react-native-fast-image'
import {scale, moderateScale, verticalScale} from '../utils/scaling';
export default class MeuScreen extends React.Component {
static navigationOptions = {
header: null,
title: null
};
render() {
let meuBg = require('../assets/images/meu_home_bg.jpg');
let meuBgSource = resolveAssetSource(meuBg);
const bgImg = <Image width={Dimensions.get('window').width} source={meuBg} style={styles.topBg}/>;
return (
<View style={styles.container}>
{bgImg}
<View style={styles.boxWrap}>
<View style={styles.roundBox}>
<View style={styles.guys}>
<Image resizeMode="cover" style={styles.me} width={60} height={60}
source={{uri: 'https://static.pexels.com/photos/213117/pexels-photo-213117.jpeg'}}/>
<Image resizeMode="cover" style={styles.you} width={60} height={60}
source={{uri: 'https://static.pexels.com/photos/213117/pexels-photo-213117.jpeg'}}/>
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'rgba(239, 244, 255, 0.36)',
position: 'relative',
alignItems: 'center'
},
topBg: {
position: 'absolute', top: 0,
zIndex: 1
},
roundBox: {
width: Dimensions.get('window').width - 60,
minHeight: 300,
borderWidth: 1,
borderColor: '#e5e5e5',
borderRadius: 30,
backgroundColor: '#fff',
marginTop: verticalScale(165),
zIndex: 2
},
guys: {
flex: 1,
marginTop: verticalScale(-25),
flexDirection: 'row',
zIndex: 3
},
me: {
borderWidth: 4,
borderColor: '#fff',
borderRadius: 30,
position: 'absolute',
top: 0, left: scale(46)
},
you: {
borderWidth: 4,
borderColor: '#fff',
borderRadius: 30,
position: 'absolute',
top: 0, right: scale(46)
},
category: {},
location: {},
dates: {}
});
First, I had to think like the web. (position and z-index)
But RN is not supported 'z-index'.
How do I work?
Please help..

please specify Image width and height, inside an Image style.
<Image resizeMode="cover" style={[styles.me,{width:60,height:60}]} source={{uri: 'https://static.pexels.com/photos/213117/pexels-photo-213117.jpeg'}}/>

Related

How can I force content within modal to be 100% the height of the modal?

I am trying to use flexbox to make the content within a Modalize view go to 100% of the Modal view. Currently, it's only going to the height of the content, and not the modal.
With this code:
<Modalize
// onOpen={onOpen}
onOpened={() => console.log("ONOPEN")}
ref={modalizeRef}
modalStyle={{ flex: 1,
backgroundColor: 'yellow',
shadowColor: '#000', shadowOffset: { width: 0, height: 6 }, shadowOpacity: 0.45, shadowRadius: 16,
}}
alwaysOpen={85}
handlePosition="inside"
>
<View style={{ flex: 1, backgroundColor: 'green' }}>
<Text>
Data here
</Text>
</View>
</Modalize>
It looks like this:
How can I make it so the green background fills the entire height of the modal?
Use Dimensions to set the height.
Sample Example: Expo Snack
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions } from 'react-native';
import Constants from 'expo-constants';
import { Modalize } from 'react-native-modalize';
const window = Dimensions.get('screen');
export default function App() {
const modalizeRef = React.useRef();
return (
<View style={styles.container}>
<Modalize
// onOpen={onOpen}
onOpened={() => console.log('ONOPEN')}
ref={modalizeRef}
modalStyle={{
flex: 1,
backgroundColor: 'yellow',
shadowColor: '#000',
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.45,
shadowRadius: 16,
}}
alwaysOpen={85}
handlePosition="inside">
<View style={{ height: window.height * 0.85, backgroundColor: 'green' }}>
<Text>Data here</Text>
</View>
</Modalize>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});

React Native: How to create a button in the header that overlays the screen content which works on Android and iOs

I am trying to achieve this layout*. And I've done it, but unfortunately, it is working only on iOs devices. On Android devices, when I press the button in the zone where it overlays the part of the screen which is not in the header doesn't work, even if it is displayed. Also, on Android this property "borderRightColor": ' doesn't seem to work properly. I didn't manage to find if those are some known bugs of the react-native framework or if is something wrong with my code. What can I do to create this layout on both platforms? I've created this snack with my code so far on this issue: https://snack.expo.io/#ivy.mihai/header-with-button-overlaying-the-screen
*Desired layout
How it looks what I've done on Android
How it looks what I've done on iOs
Put the semiCircle View before the button, and avoid zIndex.
The bottom of the button is out of its parent View, so when you touch this part of the button it doesn't work. The only workaround I could find online is to use the TouchableWithoutFeedback (or any Touchable) from the "react-native-gesture-handler" library.
This Touchable renders a bit differently, so I had to change a few things
Then I would add a few advises to go a little further :
Avoid TouchableWithoutFeedback for a button, user needs a Feedback. Prefer TouchableOpacity for ios and TouchableNativeFeedback for android.
Avoid circular icons for buttons. Prefer an icon on a circle View, the background of this View will be used for the ripple effect on android
I clarified the stylesheet and it gives the code below :
import React, { Component } from 'react'
import {
View,
StyleSheet,
Dimensions,
Platform,
TouchableNativeFeedback as RNTouchableNativeFeedback,
} from 'react-native'
import {
TouchableWithoutFeedback,
TouchableOpacity,
TouchableNativeFeedback,
} from 'react-native-gesture-handler'
import { Ionicons } from '#expo/vector-icons'
import { Button } from './src/components/BergamotUI'
const windowWidth = Dimensions.get('window').width
export default class App extends Component {
render() {
const color1 = 'red'
const color2 = 'yellow'
const Touchable = Platform.select({ ios: TouchableOpacity, android: TouchableNativeFeedback })
return (
<View style={styles.container}>
<View style={styles.header}>
<View style={styles.buttonContainer}>
<View style={styles.semiCircle} />
<View style={styles.button}>
<Touchable onPress={() => console.log('I am doing something')} useForeground={true}>
<View style={styles.iconWrapper}>
<Ionicons name="ios-add" color={'white'} size={34} />
</View>
</Touchable>
</View>
</View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
button: {
overflow: 'hidden',
borderRadius: 50,
},
iconWrapper: {
backgroundColor: 'grey',
width: 50,
height: 50,
borderRadius: 50,
justifyContent: 'center',
alignItems: 'center',
paddingTop: Platform.select({ ios: 4, android: 0 }),
paddingLeft: Platform.select({ ios: 2, android: 0 }),
overflow: 'hidden',
},
header: {
width: windowWidth,
height: 108,
borderWidth: 1,
borderColor: 'red',
alignItems: 'flex-end',
justifyContent: 'flex-end',
marginTop: Platform.OS === 'ios' ? Dimensions.StatusBarHeight : 0,
},
buttonContainer: {
position: 'absolute',
right: 10,
width: 80,
height: 40,
borderColor: 'transparent',
flex: 1,
alignItems: 'center',
paddingTop: 15,
//backgroundColor: 'blue',
},
semiCircle: {
position: 'absolute',
bottom: 0,
backgroundColor: 'transparent',
borderColor: 'red',
borderWidth: 1,
width: 80,
height: 40,
borderTopRightRadius: 40,
borderTopLeftRadius: 40,
borderBottomWidth: 1,
borderBottomColor: 'white',
},
buttonContainer2: {
borderRadius: 50,
height: 50,
overflow: 'hidden',
},
button2: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'green',
height: 50,
paddingHorizontal: 5,
},
})
Edit 1 : Add the point about the Touchable outside its parents, add TouchableNativeFeedback and TouchableOpacity and rewrote some style

Unable to create curved view in react-native

<View style={{
width: window.width,
height: window.width / 7,
backgroundColor: colors.white}}>
<View style={{
backgroundColor: colors.primary,
borderBottomLeftRadius: 80,
borderBottomRightRadius: 80,
height: window.width / 7,
width: window.width,
flex: 1,
}}>
<View style={{
backgroundColor: '#000',
height: window.width / 7,
width: window.width / 3,
borderRadius: 100,
alignSelf: 'center',
position: 'absolute',
bottom: 0,
overflow: 'hidden',
}}>
</View>
</View>
Check the below solution
import * as React from "react";
import { View, StyleSheet } from "react-native";
export default function Curve() {
return (
<View style={{ margin: 50 }}>
<View style={styles.squreStyle} />
<View style={styles.arcStyle} />
</View>
);
}
const styles = StyleSheet.create({
squreStyle: {
width: "100%",
height: 75,
borderRadius: 12,
backgroundColor: "black",
},
arcStyle: {
width: "20%",
height: 70,
position: "absolute",
bottom: -25,
left: "40%",
borderRadius: 35,
backgroundColor: "black",
transform: [{ scaleX: 5 }, { scaleY: 1 }],
},
});
Sample image of the working code
Edit - Modified according to the requirements of Scroll & Write content inside header.
import * as React from "react";
import { View, StyleSheet, Text, ScrollView } from "react-native";
export default function Curve() {
return (
<ScrollView>
<View style={{marginVertical: 50}}>
<View style={styles.squreStyle}>
<Text style={{ color: "white", textAlign: "center" }}>Sample Header</Text>
</View>
<View style={styles.arcStyle} />
</View>
<View style={{ height: 500, backgroundColor: "green" }} />
<View style={{ height: 500, backgroundColor: "yellow" }} />
</ScrollView>
);
}
const styles = StyleSheet.create({
squreStyle: {
width: "100%",
height: 75,
borderRadius: 12,
backgroundColor: "black",
zIndex: 1,
},
arcStyle: {
width: "20%",
height: 70,
position: "absolute",
bottom: -25,
left: "40%",
borderRadius: 35,
backgroundColor: "black",
transform: [{ scaleX: 5 }, { scaleY: 1 }],
},
});
Hope this helps you. Feel free for doubts.
The thing is react native doesnt let us add border radius to sides unless of same height and width so that it can be a circle. What i did is exactly created a circle and pushed it upwards with top so that it seems like this. You can control the curvature by fixing the height and width and make it dynamic so that in every screen it looks the same.
Please check code below and also the expo snack:
expo-snack
Code:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.newD}></View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
newD:{
height:500,
width:500,
backgroundColor:'red',
marginLeft:-70,
borderRadius:500,
top:-280
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
Hope it helps. feel free for doubts
You can use react-native-canvas for draw it
import {Dimensions} from 'react-native';
import Canvas from 'react-native-canvas';
const {width} = Dimensions.get('window');
...
drawArc = (canvas) => {
const height = 150;
const ctx = canvas.getContext('2d');
context.moveTo(0,height/2);
context.quadraticCurveTo(width/2, height, width, height/2);
};
...
<Canvas
ref={canvas => drawArc(canvas) />
...
Hope this helps to you.

BoxShadow in react-native

I am trying to create a box-shadow around a view in react-native version 0.59.9
I have tried 'shadowOffSet' and all shadow properties but no use
import React, { Component } from 'react';
import { Text, View, StyleSheet, PixelRatio } from 'react-native';
const styles = {
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
}
export default class Card extends Component {
render() {
return (
<View style={styles.container}>
<View style={{
borderWidth: 1,
borderRadius: 20,
borderColor: '#ddd',
borderBottomWidth: 0,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 20,
borderWidth: (1 / PixelRatio.getPixelSizeForLayoutSize(1)),
elevation: 1,
justifyContent: 'center',
alignItems: 'center',
overflow: this.props.overflow ? this.props.overflow : 'hidden',
width: 120,
height: 150}}>
<Text>Mine</Text>
</View>
</View>
);
}
}
The result is attached as screenshot
https://user-images.githubusercontent.com/14028306/60788321-0a283500-a17a-11e9-841d-5604982783ac.jpg
You can use the react native box shadow generator for the best practice.
https://ethercreative.github.io/react-native-shadow-generator/
please use this example for boxShow in react-native
import React, { Component } from 'react';
import { TouchableOpacity, StyleSheet, Text, View } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.buttonStyles}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
buttonStyles: {
backgroundColor: '#f2f2f2',
paddingVertical: 10,
width: '60%',
borderRadius: 10,
shadowColor: 'black',
shadowOpacity: 0.9,
elevation: 10,
},
welcome: {
fontSize: 20,
alignSelf: 'center',
}
});
Your code is valid on ios plateform for the bowShadow but for android you have to pass by the property elevation
Increasing the elevation parameter in your View style will increase the radius of the box-shadow on android devices:
https://snack.expo.io/S1NK7dxbr
As an aside, you have borderWidth listed twice as a style in your nested View component.

React Native - Android position absolute buttons are untappable

I have a react native component that handles comunication between two peers using WebRTC.
Everything works perfectly on ios but on android the buttons are unclickable and i am pretty sure its because of the position:absolute, the buttons rendering somewhere behind a element and because of that they are untappable.
My question is ... what am i doing wrong? Why are they rendering but they are untappable on android?
The buttons are: End call positioned center bottom and switch camera positioned right bottom.
PS: I removed most of the component logic as it was irelevant to the question.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { RTCView } from 'react-native-webrtc';
import WebSocketWrapper from '../components/generic/WebSocketWrapper/WebSocketWrapper';
import { Image, StyleSheet, View, Text, Platform, ActivityIndicator, Dimensions } from 'react-native';
import RNSecureStorage, { ACCESSIBLE } from 'rn-secure-storage';
import WebRtcPeer from 'react-native-kurento-utils';
import { COLORS } from '../styles/colors';
import { SafeAreaView } from 'react-navigation';
import axios from 'axios';
import Toast from 'react-native-root-toast';
import Icon from 'react-native-vector-icons/MaterialIcons';
import IconIonicons from 'react-native-vector-icons/Ionicons';
import { TouchableOpacity } from 'react-native-gesture-handler';
import logger from '#/logging.service';
import utils from '#/utils.service';
const BTN_CIRCLE_SIZE = 60;
const ICON_CIRCLE_SIZE = BTN_CIRCLE_SIZE / 2;
const styles = StyleSheet.create({
rtcViewsContainer: {},
remoteView: {
alignSelf: 'center',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: '#000000'
},
selfView: {
position: 'absolute',
alignSelf: 'flex-start',
width: 150,
height: 150,
left: 16,
bottom: 32,
borderWidth: 0.5
},
textContainer: {
flex: 1,
padding: 32,
width: '100%',
alignItems: 'center',
justifyContent: 'center'
},
introductionText: {
justifyContent: 'center',
alignItems: 'center',
fontSize: 13,
lineHeight: 22,
textAlign: 'center'
},
logo: {
alignSelf: 'center',
height: 70,
width: 150
},
logoContainer: {
height: 70,
position: 'absolute',
top: 0,
left: 0,
right: 0,
justifyContent: 'center',
alignItems: 'center'
},
endCallIconContainer: {
position: 'absolute',
zIndex: 100,
bottom: 32,
width: BTN_CIRCLE_SIZE,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row'
},
endCallIconTouchable: {
width: BTN_CIRCLE_SIZE,
height: BTN_CIRCLE_SIZE,
borderRadius: BTN_CIRCLE_SIZE / 2,
alignSelf: 'center',
zIndex: 110,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red'
},
switchCameraIconTouchable: {
width: BTN_CIRCLE_SIZE,
height: BTN_CIRCLE_SIZE,
borderRadius: BTN_CIRCLE_SIZE / 2,
alignSelf: 'flex-end',
zIndex: 110,
justifyContent: 'center',
alignItems: 'center'
},
switchCameraIcon: {
width: BTN_CIRCLE_SIZE,
height: BTN_CIRCLE_SIZE
},
endCallIcon: {
alignSelf: 'center'
}
});
export default class VideoCallIdentification extends Component {
static navigationOptions = {
header: null
};
displayRTCViews() {
return !!(this.state.remoteURL && this.state.videoURL);
}
getText() {
if (this.state.CALL_STATE === this.CALL_STATES.FINISHED_CALL) {
return 'Please wait ...';
} else if (this.state.REGISTERED_STATE === this.CALL_STATES.REGISTERED) {
return 'An agent will be with you soon. You will be prompted to give access to your microphone and camera in order for the video call to proceed!';
}
}
componentWillUnmount() {
this.stopCommunication();
}
getRemoveViewDimensions() {
return {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height
};
}
onSocketError(e) {
logger.log('!!!!!!!!!!!!!!! Socket Erorr!', e);
utils.toast('An unexpected error has ocurred!');
this.stopWebRtc();
this.props.navigation.navigate('CompleteAccountPage');
}
getEndCallBarSize() {
return {
left: Dimensions.get('window').width / 2 - BTN_CIRCLE_SIZE / 2,
height: BTN_CIRCLE_SIZE
};
}
getSwitchCameraBarSize() {
return {
right: 32,
height: BTN_CIRCLE_SIZE
};
}
changeCamera() {
this.webRtcConnection.toggleCamera();
}
render() {
return (
<View
style={{ marginTop: 0, paddingLeft: 0, paddingRight: 0, marginBottom: 0, flex: 1, width: '100%', ...this.getRemoveViewDimensions() }}
containerStyle={{ flex: 1, width: '100%', ...this.getRemoveViewDimensions() }}
>
<SafeAreaView style={{ ...this.getRemoveViewDimensions(), position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
{this.displayRTCViews() ? (
<View>
<View style={{ ...styles.rtcViewsContainer, ...this.getRemoveViewDimensions() }}>
<RTCView streamURL={this.state.remoteURL} style={{ ...styles.remoteView, ...this.getRemoveViewDimensions() }} />
<RTCView streamURL={this.state.videoURL} style={styles.selfView} />
</View>
<View style={{ ...styles.endCallIconContainer, ...this.getEndCallBarSize() }}>
<TouchableOpacity style={styles.endCallIconTouchable} onPress={() => this.stopCommunication(true).bind(this)}>
<Icon style={styles.endCallIcon} size={ICON_CIRCLE_SIZE} name="call-end" color="#ffffff" />
</TouchableOpacity>
</View>
<View style={{ ...styles.endCallIconContainer, ...this.getSwitchCameraBarSize() }}>
<TouchableOpacity style={styles.switchCameraIconTouchable} onPress={() => this.changeCamera(true)}>
<IconIonicons style={styles.endCallIcon} size={BTN_CIRCLE_SIZE} name="ios-reverse-camera" color="#ffffff" />
</TouchableOpacity>
</View>
</View>
) : (
<View style={styles.textContainer}>
<View style={styles.logoContainer}>
<Image source={require('../assets/images/logoAndNameColored.png')} style={styles.logo} resizeMode="contain" />
</View>
<Text style={styles.introductionText}>{this.getText()}</Text>
<ActivityIndicator style={{ marginTop: 22 }} size="large" color={COLORS.APP_PURPLE} />
</View>
)}
<WebSocketWrapper
ref={ref => {
if (!this.state.socket) {
this.setState({ socket: ref });
}
}}
onError={this.onSocketError.bind(this)}
onOpen={this.onSocketOpen.bind(this)}
url={this.state.socketUrl}
onMessage={this.onmessage.bind(this)}
/>
</SafeAreaView>
</View>
);
}
}
VideoCallIdentification.propTypes = {
navigation: PropTypes.object
};