Related
How can I achieve this in react native?
So far I have this and I want to implement the middle curve. I don't know to either handle it with a transparent view or switch to SVG completely
and this the tabBar component
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
import { TouchableOpacity, Text, StyleSheet, View } from 'react-native'
import { Colors } from 'App/Theme'
export default class TabBar extends Component {
render() {
let {
renderIcon,
getLabelText,
activeTintColor,
inactiveTintColor,
onTabPress,
onTabLongPress,
getAccessibilityLabel,
navigation,
showLabel,
} = this.props
let { routes, index: activeRouteIndex } = navigation.state
return (
<View style={styles.tabBar}>
{routes.map((route, routeIndex) => {
let isRouteActive = routeIndex === activeRouteIndex
let tintColor = isRouteActive ? activeTintColor : inactiveTintColor
return (
<TouchableOpacity
key={routeIndex}
style={styles.tab}
onPress={() => {
onTabPress({ route })
}}
onLongPress={() => {
onTabLongPress({ route })
}}
accessibilityLabel={getAccessibilityLabel({ route })}
>
{renderIcon({ route, focused: isRouteActive, tintColor })}
{showLabel ? <Text>{getLabelText({ route })}</Text> : null}
</TouchableOpacity>
)
})}
</View>
)
}
}
const styles = StyleSheet.create({
tab: {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
},
tabBar: {
alignSelf: 'center',
backgroundColor: Colors.primary,
borderRadius: 50,
bottom: 10,
elevation: 2,
flexDirection: 'row',
height: 65,
position: 'absolute',
width: '95%',
},
infinity: {
width: 80,
height: 100,
},
infinityBefore: {
position: 'absolute',
top: 0,
left: 0,
width: 0,
height: 0,
borderWidth: 20,
borderColor: 'red',
borderStyle: 'solid',
borderTopLeftRadius: 50,
borderTopRightRadius: 50,
borderBottomRightRadius: 50,
borderBottomLeftRadius: 0,
transform: [{ rotate: '-135deg' }],
},
infinityAfter: {
position: 'absolute',
top: 0,
right: 0,
width: 0,
height: 0,
borderWidth: 20,
borderColor: 'red',
borderStyle: 'solid',
borderTopLeftRadius: 50,
borderTopRightRadius: 0,
borderBottomRightRadius: 50,
borderBottomLeftRadius: 50,
transform: [{ rotate: '-135deg' }],
},
})
here is a demo: https://snack.expo.io/#nomi9995/cf371e
you need to use react-native-svg
yarn add react-native-svg
import React, { Component } from "react";
import {
Text,
StyleSheet,
View,
Dimensions,
TouchableHighlight,
} from "react-native";
import Svg, { Circle, Path } from "react-native-svg";
const tabs = [1, 2, 3, 4, 5];
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
pathX: "357",
pathY: "675",
pathA: "689",
pathB: "706",
};
}
render() {
return (
<View style={[styles.container]}>
<View style={[styles.content]}>
<View style={styles.subContent}>
{tabs.map((_tabs, i) => {
return (
<TouchableHighlight
key={i}
underlayColor={"transparent"}
onPress={() => console.log("onPress")}
>
<View>
</View>
</TouchableHighlight>
);
})}
</View>
<Svg
version="1.1"
id="bottom-bar"
x="0px"
y="0px"
width="100%"
height="100"
viewBox="0 0 1092 260"
space="preserve"
>
<Path
fill={"#373A50"}
stroke={"#373A50"}
d={`M30,60h${this.state.pathX}.3c17.2,0,31,14.4,30,31.6c-0.2,2.7-0.3,5.5-0.3,8.2c0,71.2,58.1,129.6,129.4,130c72.1,0.3,130.6-58,130.6-130c0-2.7-0.1-5.4-0.2-8.1C${this.state.pathY}.7,74.5,${this.state.pathA}.5,60,${this.state.pathB}.7,60H1062c16.6,0,30,13.4,30,30v94c0,42-34,76-76,76H76c-42,0-76-34-76-76V90C0,73.4,13.4,60,30,60z`}
/>
<Circle
fill={"#7EE6D2"}
stroke={"#7EE6D2"}
cx="546"
cy="100"
r="100"
/>
</Svg>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
overflow: "hidden",
},
content: {
flexDirection: "column",
zIndex: 0,
width: Dimensions.get("window").width - 30,
marginBottom: "4%",
left: "4%",
right: "4%",
position: "absolute",
bottom: "1%",
},
subContent: {
flexDirection: "row",
marginLeft: 15,
marginRight: 15,
marginBottom: 10,
zIndex: 1,
position: "absolute",
bottom: 5,
}
});
i hope this will help you.
Here is 2 solution according to your requirement.
If you want this type of design without selection then this code will help you :
https://github.com/alex-melnyk/clipped-tabbar
And if you need on each tab selection then here is other easy library for you :
https://github.com/Jm-Zion/rn-wave-bottom-bar
It's not obvious that this can be done with only <View/> components. I would split the TabBar into a flex row container with three subviews, and create an SVG with the filled inverted radius to be used in the center subview. To render the SVG, use react-native-svg. See a rough layout below:
...
import { SvgXml } from 'react-native-svg';
import TabCenterSvg from ‘assets/my-svg.svg’
export default class TabBar extends Component {
render() {
return (
<View style={styles.tabBar}>
<View style={styles.leftContainer}>
{/* Left Buttons */}
</View>
<View style={styles.centerContainer}>
<View style={styles.centerInnerTopContainer}>
{/* Add Button */}
</View>
<View style={styles.centerInnerBottomContainer}>
<SvgXml xml={TabCenterSvg} />
</View>
</View>
<View style={styles.rightContainer}>
{/* Right Icons */}
</View>
</View>
)
}
}
const styles = StyleSheet.create({
tabBar: {
alignSelf: 'center',
borderRadius: 50,
bottom: 10,
elevation: 2,
flexDirection: 'row',
height: 65,
position: 'absolute',
width: '95%',
},
leftContainer: {
flex: 1,
flexDirection: 'row',
borderBottomLeftRadius: 50,
borderTopLeftRadius: 50,
borderTopRightRadius: 50,
backgroundColor: Colors.primary,
},
centerContainer: {
flex: 1,
flexDirection: 'column',
},
centerInnerTopContainer: {
flex: 1,
},
centerInnerBottomContainer: {
flex: 1,
},
rightContainer: {
flex: 1,
flexDirection: 'row',
borderTopLeftRadius: 50,
borderTopRightRadius: 50,
borderBottomRightRadius: 50,
backgroundColor: Colors.primary,
},
})
Use this library's code and customize according to your UI
https://www.npmjs.com/package/curved-bottom-navigation-bar
Note: I'll not recommend this library as there are low weekly downloads.
Rather than using the whole library, you can use its code.
I am new in react native. I am designing the UI in which i want to design semi-circle or oval. i tried but the output is not as per the expectation. can we use canvas or svg in react native?
Actual:
Current:
Code.js
<View style={{ flex: 1, flexDirection: 'row' }}>
<View style={styles.circleSkyBlue}></View>
<View style={styles.circleViolet}></View>
</View>
code.css
circleViolet:{
width: 239,
height: 134,
borderBottomRightRadius: 50,
borderBottomLeftRadius: 100,
backgroundColor: '#596AB2',
transform: [
{scaleX: 1.2}
]
},
circleSkyBlue:{
width: 180,
height: 84,
borderBottomRightRadius: 100,
borderBottomLeftRadius: 50,
backgroundColor: '#69C0EC',
transform: [
{scaleX: 1}
] ,
overflow: 'hidden',
},
Any help is appreciated.
Thank you in advance
I have created a snack where you can check the example. No need to use egg here, you can use position to get the UI you want.
Snack: https://snack.expo.io/#ashwith00/ovals
Code:
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions } from 'react-native';
import Constants from 'expo-constants';
const {width} = Dimensions.get('window')
const oval1Width = width * 0.5, oval2Width = width * 0.7;
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.oval1} />
<View style={styles.oval2} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
oval1: {
position: 'absolute',
width: oval1Width,
height: oval1Width,
borderRadius: oval1Width / 2,
backgroundColor: 'red',
top: -oval2Width / 3,
left: -10,
zIndex: 3,
},
oval2: {
position: 'absolute',
width: oval2Width,
height: oval2Width,
borderRadius: oval2Width / 2,
backgroundColor: 'blue',
top: -oval2Width / 2.5,
right: -10,
zIndex:2
},
});
I am making an simple iOS app using react-native and having some problems with navigator I delcared two views but got nothing rendered but a blank page
The followed is my code:
'use strict';
var Dimensions = require('Dimensions');
import React, {
Component,
StyleSheet,
MapView,
Text,
View,
Animated,
Navigator,
TouchableHighlight,
TouchableOpacity,
Image,
PropTypes,
Modal
} from 'react-native';
var {
height: deviceHeight,
width: deviceWidth
} = Dimensions.get('window');
var BasicConfig = Navigator.SceneConfigs.FloatFromLeft;
var CustomLeftToRightGesture = Object.assign({}, BasicConfig.gestures.pop, {
snapVelocity:8,
edgeHitWidth: deviceWidth,
});
var CustomSceneConfig = Object.assign({}, BasicConfig, {
springTension: 100,
springFriction: 1,
gestures:{
pop:CustomLeftToRightGesture,
}
});
var MainMap = React.createClass({
watchID: (null: ?number),
getInitialState: function() {
return {
latitude: 0,
longitude: 0,
initialPosition: 'unknown',
lastPosition: 'unknown',
};
},
openMenu(){
this.props.navigator.push({id: 2,});
},
render: function(){
console.log("123456")
return (
<View style = {styles.container}>
<View style = {styles.TopBarContainer}>
<TouchableOpacity style={styles.toolbarButton}
onPress={this.openMenu}>
<Text style={styles.toolbarButtonText}>{"MENU"}</Text>
</TouchableOpacity>
<Text style={styles.toolbarTitle}>{"Simply Park"}</Text>
<TouchableOpacity style={styles.toolbarButton}
onPress={this.openSeacrh}>
<Image source={require('image!search')} style={styles.toolbarSeacrhImage}/>
</TouchableOpacity>
</View>
<MapView
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
/>
</View>
);
}
});
var ControlPanel = React.createClass({
_handlePress(){
this.props.navigator.pop();
},
render: function() {
console.log("paaaaaaaaanel")
return (
<View style={styles.container}>
<Text style={styles.controlText}>{"Control Panel"}</Text>
<TouchableOpacity style={styles.button} onPress={this._handlePress}>
<Text>{"Close Drawer"}</Text>
</TouchableOpacity>
</View>
)
}
});
var Main = React.createClass({
_renderScene(route, navigator){
if (route.id === 2){
console.log("id is 2");
return <ControlPanel navigator={navigator} />
}else{
console.log("id is 1");
return <MainMap navigator={navigator} />
}
},
_configureScene(route){
return CustomSceneConfig;
},
render(){
console.log("hihihihihihi");
return(
<Navigator
initialRoute={{
id: 1,
}}
renderScene = {this._renderScene}
configureScene = {this._configureScene}
/>
);
}
});
const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'flex-end',
alignItems: 'center',
},
TopBarContainer:{
position: 'absolute',
backgroundColor: '#3b5998',
top: 0,
left: 0,
right: 0,
bottom: 580,
flexDirection:'row'
},
toolbarButton:{
paddingTop:35,
paddingLeft: 7,
width: 50,
alignItems:'center'
},
toolbarButtonText:{
paddingTop: 5,
color:'#fff',
fontWeight: 'normal',
fontSize: 13,
},
toolbarTitle:{
paddingTop:35,
color:'#fff',
textAlign:'center',
fontWeight:'bold',
fontSize: 18,
flex:1,
},
toolbarSeacrhImage:{
paddingTop: 20,
width: 18,
height:18,
},
map: {
position: 'absolute',
top: 70,
left: 0,
right: 0,
bottom: 0,
},
controlText: {
color: 'white',
},
button: {
backgroundColor: 'white',
borderWidth: 1,
borderColor: 'black',
padding: 10,
bottom: 500,
},
});
module.exports = Main;
I put console.log() for debug use. The debug texts displayed properly on the debug xcode dubug console however the MainMap view is not displayed. I am wondering if this is a problem with my view styles but no clue after several tries.
An answer to my question is I am using modal to transit between previous scene to this scene, and removed justifyContent: 'flex-end', alignItems: 'center' from the previous scene where this view is rendered。
Try adding style={{flex: 1}} to the navigator.
<Navigator
style={{ flex: 1 }}
initialRoute={{
id: 1,
}}
renderScene = {this._renderScene}
configureScene = {this._configureScene}
/>
I am young to react native search the web for tutorials that could help me with this problem but have not find anything. I know how to move the buttons from point A to B on my screen. The thing is I just cant seem to get it to be fixed at the bottom to work on different form factors of my ios emulator.
So far I have tried marginTop which takes down the button to the screen but as soon as a I change the emulator to a different screen size the button goes up a little. I am asking can I get any guidance as how I may set this to work on different ios screens.
submitButton: {
height: 85,
flex: 1,
backgroundColor: "#FFBB34",
borderColor: "#555555",
borderWidth: 0,
borderRadius: 0,
marginTop: 200,
justifyContent: "flex-start"
}
The code above is my button.
You can use absolute position to put things wherever you want...
submitButton: {
position: 'absolute',
bottom:0,
left:0,
}
will put at bottom of screen, left side....
Here is how I placed the floating button at the bottom-right of the screen.
return (
<View style={mainConatinerStyle}>
{this.renderSwiper()}
{this.renderFloatingMenu()}
</View>
);
Use the following styles for container & button:
mainConatinerStyle: {
flexDirection: 'column',
flex: 1
},floatingMenuButtonStyle: {
alignSelf: 'flex-end',
position: 'absolute',
bottom: 35
}
Output:
You can try the code below at https://facebook.github.io/react-native/docs/flexbox.html until that link doesn't work anymore.
Basically you are splitting the screen into 3 pieces, top scrollable, and bottom. The code below is just doing 3 views for simplicity (no scrolling, just replace the middle one with a ScrollView to have somethign more useful.
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class JustifyContentBasics extends Component {
render() {
return (
// Try setting `justifyContent` to `center`.
// Try setting `flexDirection` to `row`.
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
}}>
<View style={{height: 50, backgroundColor: 'powderblue'}} />
<View style={{flex:1, backgroundColor: 'skyblue'}} />
<View style={{height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
the element
<View style={style.viewBtn}>
<TouchableOpacity style={style.btn} onPress={() => {}}>
<Text style={style.txtBtn}>Send</Text>
</TouchableOpacity>
</View>
the CSS
viewBtn: {
position: 'absolute',
bottom: 0,
height: window.height * 0.1,
width: window.width * 1,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
btn: {
height: window.height * 0.07,
width: window.width * 0.8,
backgroundColor: colors.cornflower,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
},
txtBtn: {
textAlign: 'center',
fontSize: 21,
color: 'white',
fontWeight: 'bold',
},
hope this code help your problem, dont forget to use dimension to set height and weight, but optional to use the dimension
I am able to get it to the center without the mapview but I cant seem to get the image to the center with mapview. anyone able to do it on react native?
render() {
return (
<View style = { styles.container }>
<MapView style = { styles.mapView }></MapView>
<View style = { styles.mapCenterMarkerView }>
<Image style={styles.mapCenterMarker}
source={{uri: this.state.markerIcon}}/>
</View>
);
}
var styles = StyleSheet.create({
container: {
flex: 1,
},
mapView: {
flex: 1
},
mapCenterMarkerView: {
top: 0,
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0)',
},
mapCenterMarker: {
width: 32,
height: 32,
},
});
I was able to get the result you're looking for, but I had to remove the flex styling from the MapView.
https://rnplay.org/apps/TQGKjA
It looks like MapView doesn't allow child nodes. There's probably a way to do this without resorting to position: 'absolute' for the MapView but I'd have to play with it some more.
If you're new to flexbox like me, I've found this to be a good resource:
flexboxin5.com
class SampleApp extends React.Component {
render() {
return (
<View style={ styles.container }>
<MapView style={ styles.mapView }></MapView>
<View style={styles.mapCenterMarker} />
</View>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0)',
},
mapView: {
position: 'absolute',
top: 20,
bottom: 0,
left: 0,
right: 0,
},
mapCenterMarkerView: {
flex: 1,
},
mapCenterMarker: {
width: 32,
height: 32,
backgroundColor: 'black'
},
});
I move the justifyContent: 'center' down from container for it to work. thank to you because i have a inside the .
container: {
flex: 1,
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0)',
},
mapView: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
mapCenterMarkerView: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0)',
},
mapCenterMarker: {
width: 32,
height: 32,
backgroundColor: 'rgba(0,0,0,0)'
},