Related
I want to do something like as shown in the image below but I don't have any idea how to achieve that (I googled it, but I found only result for native code Swift, Obj C, ...).
Do I have to play with some layers or something like that?
Thanks for your answers!
Viktor
Hey thank you so much for your answers,
I had to handle the text overflow with ellipsis and it was really complicated with what you proposed, so I used the maskView to do that.
I did like that:
// container
<View style={{flex:1, borderRadius: 200, height: 25, overflow:hidden}}>
// Progress bar support
<View style={{flex:1, backgroundColor: 'gray'}} />
// Progress bar, I play with "width" to indicate percentage
<View style={[StyleSheet.absoluteFill, {width: "50%", backgroundColor: 'green'}]} />
<MaskedView
style={[StyleSheet.absoluteFill, {justifyContent: 'center'}]}
maskElement={
// I define text which will be masked
<View style={[StyleSheet.absoluteFill, {justifyContent: 'center'}]}>
<Text
style={{marginHorizontal: 15, fontSize: 13}}
numberOfLines={1}>
Text color change
</Text>
</View>
}>
// I define a default mask that I apply to the text so that it is 'black' when it is not ON the progress bar.
<View style={[StyleSheet.absoluteFill,{backgroundColor: 'black'}]} />
// I define the mask that takes the size of the progress bar and that I apply over the default mask (to overwrite it) so that the text under the mask becomes white.
<View style={[StyleSheet.absoluteFill,{width:"50%", backgroundColor: '#fff'}]} />
</MaskedView>
</View>
So I have my default bar indicating the "maximum progress" and I define my progress bar (which grows or shrinks according to the percentage).
Then I define a MaskedView with my text as MaskedElement.
By default, I apply a black mask on the text so that it is always black no matter what happens.
And then, I overwrite this mask with the white mask which has exactly the same size as my progress bar.
So everything under the mask of the progress bar becomes white to go on my "dark" progress bar and the rest is black!
This way, I can easily manage the text overflow with an ellpsizeMode="tail".
And this is the result:
Same styles from the previous answer but changed the implementation by adding another View that contains same text with different background color and text color inside the gray one with a position of 'absolute'!
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default class Example extends React.Component {
state = {
text: 'Text color changes',
};
render() {
console.log(this.state.textArray);
return (
<View style={styles.container}>
<View
style={{
flex: 1,
backgroundColor: '#d0d3d6',
borderTopRightRadius: 20,
borderBottomRightRadius: 20,
borderTopLeftRadius: 20,
borderBottomLeftRadius: 20,
overflow: 'hidden',
}}>
<Text style={styles.leftLabelStyle}>{this.state.text}</Text>
<View
style={{
width: '30%',
height: '100%',
position: 'absolute',
backgroundColor: '#5483b3',
}}>
<Text numberOfLines={1} ellipsizeMode='clip'
{styles.RightLabelStyle}>
{this.state.text}
</Text>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 20,
},
leftLabelStyle: {
fontSize: 16,
paddingVertical: 5,
color: '#000',
},
RightLabelStyle: {
fontSize: 16,
paddingVertical: 5,
color: '#fff',
},
});
example at snack:https://snack.expo.io/#hassan190011/loading
Edit : add ellipsizeMode='clip' after numberOfLines to remove dots
This implementation is a little bit different, Mainly I have 2 different views with separate styles & Finally, wrap those 2 views using the main view.
import * as React from "react";
import { Text, View, StyleSheet } from "react-native";
export default class Example extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.leftViewStyle}>
<Text style={styles.leftLabelStyle}>Text color ch</Text>
</View>
<View style={styles.rightViewStyle}>
<Text style={styles.rigthLabelStyle}>ange</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
marginHorizontal: 20
},
leftViewStyle: {
flex: 1,
backgroundColor: "#5483b3",
alignItems: "flex-end",
borderTopLeftRadius: 20,
borderBottomLeftRadius: 20
},
rightViewStyle: {
flex: 1,
backgroundColor: "#d0d3d6",
borderTopRightRadius: 20,
borderBottomRightRadius: 20
},
leftLabelStyle: {
fontSize: 16,
paddingVertical: 5,
color: "#fff"
},
rigthLabelStyle: {
fontSize: 16,
paddingVertical: 5,
color: "#000"
}
});
This might not be the optimal solution. If you have any doubts feel free to ask.
Hope this will helps you.
Hi I want to set Text in center, I tried justifyContent and alignItems to center but it didn't work for me, text is displaying at the top.
LoginScreenStyles.js
export default StyleSheet.create({
...ApplicationStyles.screen,
container: {
paddingBottom: Metrics.baseMargin
},
centered: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
ApplicationStyles.js
const ApplicationStyles = {
screen: {
mainContainer: {
flex: 1,
backgroundColor: Colors.transparent
},
backgroundImage: {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0
},
container: {
flex: 1,
paddingTop: Metrics.baseMargin,
backgroundColor: Colors.transparent
},
section: {
margin: Metrics.section,
padding: Metrics.baseMargin
},
sectionText: {
...Fonts.style.normal,
paddingVertical: Metrics.doubleBaseMargin,
color: Colors.snow,
marginVertical: Metrics.smallMargin,
textAlign: "center"
},
subtitle: {
color: Colors.snow,
padding: Metrics.smallMargin,
marginBottom: Metrics.smallMargin,
marginHorizontal: Metrics.smallMargin
},
titleText: {
...Fonts.style.h2,
fontSize: 14,
color: Colors.text
}
},
darkLabelContainer: {
padding: Metrics.smallMargin,
paddingBottom: Metrics.doubleBaseMargin,
borderBottomColor: Colors.border,
borderBottomWidth: 1,
marginBottom: Metrics.baseMargin
},
darkLabel: {
fontFamily: Fonts.type.bold,
color: Colors.snow
},
groupContainer: {
margin: Metrics.smallMargin,
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center"
},
sectionTitle: {
...Fonts.style.h4,
color: Colors.coal,
backgroundColor: Colors.ricePaper,
padding: Metrics.smallMargin,
marginTop: Metrics.smallMargin,
marginHorizontal: Metrics.baseMargin,
borderWidth: 1,
borderColor: Colors.ember,
alignItems: "center",
textAlign: "center"
}
};
export default ApplicationStyles;
LoginScreen.js
import React, { Component } from "react";
import { View, Text } from "react-native";
// Styles
import styles from "./Styles/LoginScreenStyles";
export default class LoginScreen extends Component {
render() {
return (
<View style={styles.mainContainer}>
<Text style={styles.centered}>
This probably isn't what your app is going to look like. Unless your
designer handed you this screen and, in that case, congrats! You're
ready to ship. For everyone else, this is where you'll see a live
preview of your fully functioning app using Ignite.
</Text>
</View>
);
}
}
You need to write
justifyContent: "center", alignItems: "center"
in container like this :
container: {
paddingBottom: Metrics.baseMargin,
justifyContent: "center",
alignItems: "center"
}
If you just want to make text center you can use alignSelf: 'center' in centered
The style for container code should include this:
justifyContent: "center",
alignItems: "center"
and NOT to the Text itself. But if you want to make the Text center themselves then you should add this:
alignSelf: 'center'
To the Text styles itself. You can get an example from the official source here for more information.
I Believe this Might Clear your concept
1. justifyContent : helps you to control content of View Vertically
2. alignItems: helps you to control content of View Horizontally
3. alignSelf : help you make Text content Center.
Run Sample code for Demonstration.
render() {
return (
<View style={styles.container}>
<View style={{ justifyContent: "center", height: 200 }}>
<Text>justifyContent works in an View vertically</Text>
<Text>center,flex-start,flex-end</Text>
</View>
<View style={{ alignItems: "center" }}>
<Text>alignItems works in an View Horizontily</Text>
<Text>center,flex-start,flex-end</Text>
</View>
<Text style={styles.textStyle}>To Make Text Center</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1
},
textStyle: {
alignSelf: "center",
alignItems: "center"
}
});
<TouchableOpacity
style = {styles.submitButton}
onPress = {
() => this.login(this.state.email, this.state.password)
}>
<Text style = {styles.submitButtonText}> Submit </Text>
</TouchableOpacity>
for text center
submitButtonText:{
color: 'white',
alignSelf: 'center'
}
Updated:-
AnyText: {
textAlign: 'center',
fontSize: 21,
fontWeight: 'bold',
}
I'm trying to make two nested swipers on Android with React Native, using react-native-swiper. Each swiper works correctly when is separate, but when I add one to the other, the inner nested swiper doesn't show any content. It's a little bit weird, it recognized its children, I can swipe but Views are not rendered. Here is my simple demonstration example:
import React from 'react'
import {
Text,
View
} from 'react-native'
import Swiper from 'react-native-swiper'
const Dimensions = require('Dimensions');
const window = Dimensions.get('window');
var styles = {
wrapper: {
backgroundColor: 'transparent'
},
innerSwiper: {
width: window.width,
height: window.height / 3,
marginTop: 60,
backgroundColor: '#92BBD9'
},
slide1: {
flex: 1,
alignItems: 'center',
backgroundColor: '#9DD6EB'
},
slide2: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#97CAE5'
},
slide3: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#92BBD9'
},
text: {
color: '#fff',
fontSize: 30,
fontWeight: 'bold'
}
}
export default () =>
<Swiper style={styles.wrapper} showsButtons>
<View style={styles.slide1}>
<View style={styles.innerSwiper}>
<Swiper style={styles.wrapper} showsButtons>
<View style={styles.slide1}>
<Text style={styles.text}>Hello Swiper</Text>
</View>
<View style={styles.slide2}>
<Text style={styles.text}>Beautiful</Text>
</View>
<View style={styles.slide3}>
<Text style={styles.text}>And simple</Text>
</View>
</Swiper>
</View>
</View>
<View style={styles.slide2}>
<Text style={styles.text}>Beautiful</Text>
</View>
<View style={styles.slide3}>
<Text style={styles.text}>And simple</Text>
</View>
</Swiper>
I've recently added react-native-navigation to my project, and now I can't get imported stylesheet to work. What I'm trying to do is this:
import screenstyles from './screenstyles';
class Screen extends Component {
render() {
return (
<View style={screenstyles.container}>
<Text style={screenstyles.basictext}>Text I want to display</Text>
</View>
);
}
screenstyles.js:
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '$primaryBlue'
},
basictext: {
color: "#fff",
fontSize: 34
}
});
But I simply get a default white screen with unstyled text.
The only way I get any sort of imported styling to work at the moment is by doing this
import {Container, styles} from '../components/Container';
class Screen extends Component {
render() {
return (
<Container backgroundColor={"red"}>
</Container>
);
}
}
Container.js:
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
},
text: {
color: '#fff',
fontSize: 30,
fontWeight: '500'
}
});
const Container = ({onPress, backgroundColor, texttest}) => (
<View style={[styles.container, {backgroundColor}]}>
<Text style={styles.text}></Text>
</View>
);
export default Container;
This approach isn't the best because it makes it much more difficult to use the same stylesheet for each screen but still being able to customize the screen.
Try rewriting the screenstyles.js file as follows:
const React = require('react-native-extended-stylesheet');
const { EStyleSheet } = React;
var styles = EStyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '$primaryBlue'
},
basictext: {
color: "#fff",
fontSize: 34
}
});
module.exports = styles;
I am trying to make my application button in react-native like below
I am using inbuilt Button view of react native where I see that it does not allow to change the height also. I want to change the height as well rounded like expected image.
This is how my button is looking :
<Button
title="CONTINUE"
color="#FE434C"
onPress={() => navigate("EnableNotification")}
/>
So this is what I usually do:
<TouchableOpacity onPress={() => {/* do this */}}>
<View style={{
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 15
}}
>
<Text style={{ color: 'white' }}>Button</Text>
</View>
</TouchableOpacity>
I find using this method makes buttons much more customisable, but if you do some digging there could be a library which implements something similar (I never really found the need to search for it).
NOTE: Obviously you will have to adjust the height/width of the button to your flavor.
EDIT: My mistake... I had put the onPress prop in the view, woops.
Here is my solution to easily style buttons using TouchableOpacity, Text and StyleSheet:
import React, { Component } from 'react';
import { View, StyleSheet, TouchableOpacity, Text } from "react-native";
export default class CustomButton extends Component {
render(){
return (
<View style={styles.container}>
/* Custom Button */
<TouchableOpacity
style={styles.customBtnBG}
onPress={() => {}} >
<Text style={styles.customBtnText}>Button</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
/* Here, style the text of your button */
customBtnText: {
fontSize: 40,
fontWeight: '400',
color: "#fff",
},
/* Here, style the background of your button */
customBtnBG: {
backgroundColor: "#007aff",
paddingHorizontal: 30,
paddingVertical: 5,
borderRadius: 30
}
});
#Ryan Turnbull, Well, i think a little padding and fontSize will do.
<TouchableOpacity onPress={() => this.onLogin()}>
<View
style={{
backgroundColor: 'black',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 15,
padding: 15,
}}>
<Text style={{color: 'white', fontSize: 20, fontWeight: '800'}}>
Button
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress = {() => {/* do this */}}>
<View style = {{backgroundColor: 'red', alignItems: 'center',
justifyContent: 'center', borderRadius: 15}}
>
<Text style = {{color: 'white'}}>Button</Text>
</View>
You can use Touchable Opacity and it's prop border radius to adjust it's curve.
https://facebook.github.io/react-native/docs/touchableopacity
In React-native, we can customise user defined button component and call it from anywhere. So that we can have structured approach throughout the program or application.
import React from "react";
import { StyleSheet, TouchableOpacity, Text, View } from "react-native";
const MyButton = props => {
return (
<TouchableOpacity
onPress={props.onPress}
>
<View style={{...styles.buttonStyle, ...props.style,
backgroundColor:props.buttonColor,
borderColor:props.buttonColor}}>
<Text style={{...styles.TextStyle, ...props.style,
color:props.fontColor}}>
{props.children}
</Text>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
buttonStyle: {
paddingVertical: 10,
paddingHorizontal: 10,
borderRadius: 10,
borderWidth: 2,
},
TextStyle: {
textAlign: "center",
},
});
export default MyButton;
In style ... spread operator is used to integrate all the styles from same components and incoming styles from parent component through props.
props.children is used here to pass button title, so that title text is displayed on the button.
When button is pressed then instead of handling this press event inside of the button but inside of the component where we use this button. So we pass a fitting function reference on the button.
This MyButton button component can be called anywhere inside the program like:
<MyButton onPress={() => onPressFunction()}
buttonColor="red" fontColor="white">Button Title</MyButton>
You can use this library https://github.com/APSL/react-native-button to create a customizable button in react native.
<View>
<Button
style={{
backgroundColor: "#FE434C",
borderColor: "transparent",
borderRadius: 20,
width: 250,
height: 50,
}}
textStyle={{ color: "#FFFFFF" }}
onPress={() => { }}
>
CONTINUE
</Button>
</View>