How do i center the Title on React Natives ToolbarAndroid? - react-native

I am using the ToolbarAndroid where i need to center the Toolbars Title. I coudn´t figure out how this works. With the Styles properties it didn´t work.
This is my code:
<ToolbarAndroid
title={toolbarTitle(this.props.activeTab)}
titleColor='white'
style={styles.toolbar}
actions={toolbarActions(this.props.activeTab)}
onActionSelected={this._onActionSelected.bind(this)}>
</ToolbarAndroid>
Toolbar style:
toolbar: { height: 50, backgroundColor: 'grey' }
I can render the title properties and other properties depending on which Tab i am (using scrollable-tab-view) but changing the position where my title is placed didn´t work on my approach

You can add a custom view inside the toolbar
<ToolbarAndroid>
<View style={styles.title}>
<Text>Hi there</Text>
</View>
</ToolbarAndroid>
and center its text
var styles = StyleSheet.create({
title: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
marginRight: 28
}
});
A margin was needed to get alignment right.
In some cases I've seen that it was necessary to set an extra style property like backgroundColor for the alignment to work.

By design guidelines toolbar title is aligned to the left. There are some hacky ways to do this in java, but it is probably impossible in react native.
If you don't mind android design guidelines I advise you to use custom component instead of ToolbarAndroid.

Related

Text not centring despite style from stylesheet

I'm trying to make a basic tab application with React Navigation and so I have three pages with plain text. They centre vertically but not horizontally on the tabs. This is using alignContent and justifyContent in conjunction with each other (which has worked for me in the past).
At first I suspected the flex was only flexing vertically and so I applied a contrasting colour. However it seems to span the tab. I have also tried textAlign, but neither cases seem to work.
This is an example of one of the screens:
export class ExampleScreen extends Component {
render() {
return(
<View style={styles.container}>
<Text>Example!</Text>
</View>
)
}
}
And here is the StyleSheet:
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
alignContent: 'center',
justifyContent: 'center'
}
})
There are no error messages. However I would expect the text to centre horizontally but all I get is this:
Your text is not horizontally center because Text is taking full width of the screen,
you need to center content inside Text
<Text style={{ textAlign: 'center' }}>Example!</Text>

Cannot change width and height of custom component in React-native?

I have a minimal custom stateless component like this:
const ViewBox = (props) => (
<View style={ mainStyle : {backgroundColor: 'beige'} }>
{props.children}
</View>
)
export default ViewBox;
so I want to import and use it inside another component.
export default class Test extends React.Component {
render() {
return (
<View style={styles.containerView} >
<ViewBox style={styles.mainBox}>
<Text style={[styles.boxTitle, {color: '#8F468C'}]}>Lorem ipsum...</Text>
</ViewBox>
</View>
);
}
}
const styles = {
containerView: {
flex: 1,
marginTop: 50,
alignItems: 'center',
backgroundColor: 'brown',
},
mainBox: {
flex: 1,
width: 250, //No effect ! ! !
height: 250 //No effect ! ! !
},
boxTitle: {
backgroundColor: 'pink',
fontSize: 17,
marginTop: 20
}
};
Here we have at least 2 inexplicable facts:
1) and more important the width and height of the ViewBox (or every custom component you want to use here) is totally out of control! Assigning numeric size or Flex values has no effect and ViewBox keeps the minimum width/height needed to render the inner Text.
2) Removing the root View (so the ViewBox became the root) ViewBox continue ignoring any size, but now it fills all the space available.... WHY???
All mentioned behavoirs occurs using a custom View (ViewBox in this case), instead if replace it with a normal View all works as expected.
I guess to know enough flex and UI best practices for React-native, but such two cases are not well covered by docs. Hope somebody can surprise me!
This is actually how flexbox works:
Flex containers come with flexShrink: 1 by default meaning that they will shrink to their contents. Adding flexShrink: 0 changes that. You may need to use minWidth and minHeight with that instead.
The reason why it stretches is because there's nothing to tell it otherwise. Your container has the default alignItems: 'stretch' overwritten with alignItems: 'center' which shrinks its contents.
Have a look at the example code on Snack: https://snack.expo.io/B1VdUma1M
There's a really nice flexbox cheatsheet/playground that shows the behaviour at: https://yoksel.github.io/flex-cheatsheet/
Bear in mind React Native's implementation is slightly different.

Center Image React Native Loading Screen

Background
I have an image placed on a screen meant to show when the screen loads other content.
I want to center the image so it is always center on all devices.
Problem
Currently the image shows up top center. I would like it to be aligned vertically as well. Also to be sure that it will always look the same on all devices.
Question
What is the solution to make sure the image is always centered and the right size for all devices?
Example,
My current code,
In Photoshop
Image is 300 Resolution
Height is 776 px
Width is 600 px
I want the image to be centered horizontally and vertically in all devices and look good without pixelating. Natively I know I need to set the image sizes. But from my understanding in React Native I can use on image but then use JSX to handle it being responsive.
import React from 'react';
import {
StyleSheet,
View,
Image,
} from 'react-native';
const logo = require('../images/logo.jpg');
const LoadingScreen = () => (
<View>
<Image
style={styles.logo}
source={logo}
/>
</View>
);
const styles = StyleSheet.create({
logo: {
justifyContent: 'center',
alignItems: 'center',
width: 300,
height: 400,
},
});
export default LoadingScreen;
You need to set the style of <View> for justifyContent and alignItems for centering the <Image>.
Should be like this :
const LoadingScreen = () => (
<View style={styles.container}>
<Image
style={styles.logo}
source={logo}
/>
</View>
);
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
logo: {
width: 300,
height: 400,
},
});
Or you can use alignSelf on the <Image> to make it center, but it will still need to add justifyContent on <View> to make it center vertically.
The View container should have styling as
flexDirection: 'column'
justifyContent: 'center'
alignItems: 'center'
height: '100%'
The height makes sure it spans throughout the page, thus making the image become both vertically and horizontally aligned.
For the image size, I think using percentage will do the trick instead of defining definite width/height.
Set in view:
justifycontent:center
And in child:
alignself:center
And perform in task.
Set in parent view:
justifycontent:center
And in child set:
alignself:center

How to override style in NativeBase?

In every code example mentioned in NativeBase Docs, there's no usage of React StyleSheet.
I didn't find a way to override styles of NativeBase.
How can I include React StyleSheet into my app?
NativeBase uses a different approach to add styling to your component.
It uses a Utility first approach, wherein it leverages the ReactNative stylesheets API and adds a layer of Utility Props on top of it. The idea is to pass props to your component to change their styling, instead of defining a className and adding styles in a separate stylesheet.
For example, with React Native, you would write:
function Example() {
return (
<View style={styles.container}>
{/* content */}
</View>;
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#0891b2',
paddingVertical: 16,
paddingHorizontal: 12,
borderRadius: 5,
alignSelf: 'center',
width: 375,
maxWidth: '100%'
}
});
Now, with NativeBase, to achieve the same view, you would write it as follows:
function Example() {
return (
<NativeBaseProvider>
<Box bg="primary.600" py="4" px="3" rounded="md" width={375} maxWidth="100%">
{/* content */}
</Box>
</NativeBaseProvider>;
);
}
Here, NativeBase has already defined bg, py, px, etc. as props and mapped them to the styling properties of backgroundColor, paddingVertical , paddingHorizontal, etc. respectively.
There is a list of these mappings provided here, which you can simply refer to add any styling that you may need for your component.
For NativeBase usually if you want customize the appearance you need to do it at a theme level and not a component/widget level.
http://nativebase.io/docs/v0.5.2/customize
I believe the reason it this keeps the UI consistent.
Have a look at the source code for all the widgets that you are trying to override the style for:
https://github.com/GeekyAnts/NativeBase/blob/master/Components/Widgets/
There are certain cases where you can amend certain aspects e.g. for the button
this.props.style is used anywhere but this.props.textStyle
So you can override the textStyle when you define the component:
<Button textStyle={{...}}/>
https://github.com/GeekyAnts/NativeBase/blob/master/Components/Widgets/Button.js

Does it exist an equivalent of box-sizing: border-box in flexbox for React Native?

I would like the size of my boxes not to be changed by margin and padding.
React Native styles all views as if box-sizing: border-box is set. See this code: https://github.com/facebook/react-native/blob/5aa1fb3ff326a429e33a443576da866f2a63c20c/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java#L632
As mentioned in another answer, In React Native, everything is treated as if as if box-sizing: border-box is set.
A workaround to simulate css content-box is to wrap your component in a container View, and add your border and padding to that View.
react native don't have an option for
boxSixing: "border-box"
what you can do in your styling is this
<View style={ {
flex: 1,
alignContent: "center",
justifyContent: "center",
}}>
<View style={ {
flex: 1,
width: "95%" // or width of the box - intended margin
}}>
***chi;dren goes here***
<View/>
<View/>
Any component that goes into that view will be at the center With a margin of 5% or whats is specified, which solves the issue for now till react-native provides a better solution
Let O (for outer) = (top, left, bottom, right) be the rectangle that represents the size
* and position of a view V. Since the box-sizing of all React Native views is border-box, any
* border of V will render inside O.
you can use resizeMode: 'cover' or 'stretch' or 'contain'