ToolbarAndroid not rendering - react-native

I'm trying to use ToolbarAndroid on my React Native Project.
But the Toolbar is not being rendered. Am I missing anything?
Here's the snippet:
toolbar.js
import React, {
Component
} from 'react';
import {
View,
Text,
ToolbarAndroid,
StyleSheet
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class Toolbar extends Component {
render() {
return(
<Icon.ToolbarAndroid
title = {this.props.title}
titleColor = 'black'
navIconName = "android-menu"
style = {styles.toolbar}
/>
);
}
}
const styles = StyleSheet.create({
toolbar: {
backgroundColor: 'firebrick',
height: 56
}
});
I've then imported this file to my main file where the component gets rendered.
UPDATE
I applied width to the toolbar and now it's showing. But why should we have to use width and what's the appropriate value to make the toolbar render along whole screen ?
Is it a bug ?
Updated style
const styles = StyleSheet.create({
toolbar: {
backgroundColor: 'firebrick',
height: 56,
width: 300
}
});

This is a working example of such component (but not the same):
<ToolbarAndroid
title = {this.props.title}
titleColor = 'black'
navIconName = "android-menu"
>
<View style={styles.toolbar}>
<Text>{this.props.title}</Text>
</View>
</ToolbarAndroid>
You have to pass a child view to ToolbarAndroid. Also using color names like firebase is not supported out of the box.

Related

React-Native-Elements Tooltip non functional

I'm trying to add a tooltip component to my react native project, I installed React Native Elements to do this. I know it's installed correctly because the Divider component worked perfectly fine. For some reason though, the tooltip doesn't seem to work right, there are no errors but it simply doesn't do anything when I tap on the tooltip.
My entire component is here:
import React from 'react';
import {
StyleSheet,
View,
TouchableOpacity,
} from 'react-native';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import { Tooltip, Text } from "#rneui/themed";
import {Colors} from './Colors';
const InfoTooltip = ({ label, info='' }) => {
return (
<View style={styles.inputLine}>
{ info != '' &&
<Tooltip popover={<Text>Tooltip Info</Text>}>
<Text>Press</Text>
</Tooltip>
}
{ info === '' &&
<Text style={styles.inputLabel}>{label}:</Text>
}
</View>
);
};
const styles = StyleSheet.create({
inputLine: {
flex: 1,
flexDirection: 'row',
},
inputLabel: {
color: Colors.Dove_Gray,
marginTop: 2,
fontSize: 14,
},
infoText: {
color: Colors.Silver,
fontSize: 12,
},
});
export default InfoTooltip;
I'm testing it on iOS and I see the text that says "Press", but when tapped, nothing happens, no popover, no error.
When setting visible to true, the tooltip is shown when I first render the app, but it locks the app up and I can no longer tap anything or scroll.
I'm not sure what I'm doing wrong, Thanks!
Starting with React Native Elements version 4.0, Tooltip is stateless. This means you need to use useState. You should declare a variable, like:
const [open, setOpen] = useState(false);
And include visible, onOpen & onClose Props for it to work:
<Tooltip
visible={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
popover="This is the popover text"
/>
More info in the Migration Guide.

Why does the React navigation bottom bar cover the layout?

I have a bottom bar like in the picture, but this bar prevents the bottom of my pages from appearing. How can I give the bottom of the page as much space like the height of the bottom bar? Thanks in advance.
This is something similar I did with but with the StatusBar. It should be very similar.
// component which allows view to remain within the safe area of a phone based on its platform
import React from "react";
import Constants from "expo-constants";
import { SafeAreaView, StyleSheet, View } from "react-native";
function Screen({ children, style }) {
return (
<SafeAreaView style={[styles.screen, style]}>
<View style={[styles.view, style]}>{children}</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: {
paddingTop: Constants.statusBarHeight,
// prevents cutoff when scrolling, grows components with the entire screen
flex: 1,
},
view: {
flex: 1,
},
});
So, since you're trying to do the same thing with the tab bar, I suggest first getting the height of the tab bar (or the extra styling you put over the tab bar) and build a Screen component to encapsulate everything you want to put on the screen:
import React from "react";
import { SafeAreaView, StyleSheet, View } from "react-native";
function Screen({ children, style }) {
return (
<SafeAreaView style={[styles.screen, style]}>
<View style={[styles.view, style]}>{children}</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: {
paddingBottom: <INSERT HEIGHT HERE>,
// prevents cutoff when scrolling, grows components with the entire screen
flex: 1,
},
view: {
flex: 1,
},
});

ImageBackground React Native doesn't show itself unless I give it the height even though the image is in the same folder

I am learning React Native and I am having trouble displaying the ImageBackground component.
The ImageBackground has source that points to an image in the same folder, despite this is still not visible unless I give the ImageBackground a height in number, because if I try to give it a height in % it still won't show itself.
Here is the code for the component execpt the style:
import React from 'react';
import { View, ImageBackground, StyleSheet, Text } from 'react-native';
export default function WelcomeScreen(props) {
return (
<View>
<Text>Welcome</Text>
<ImageBackground source={require('./background.jpg')} style={styles.background} />
</View>
);
}
Trying different ways to style it, the ImageBackground has different behaviors regarding showing itself:
This will not show ImageBackground:
const styles = StyleSheet.create({
background: {
flex: 1,
},
});
This won't either:
const styles = StyleSheet.create({
background: {
flex: 1,
height: '100%',
},
});
This will show it:
const styles = StyleSheet.create({
background: {
flex: 1,
height: 300,
},
});
I do not understand why this happens. From my understanding the size should be added only when the image is from the net, and regardless this, the % value should still work.
What am I missing here?
EDIT:
I made a workaround for this using Dimension and feeding the screen height to the ImageBackground:
import { View, ImageBackground, StyleSheet, Dimensions } from 'react-native';
const { height } = Dimensions.get('screen');
const styles = StyleSheet.create({
background: {
flex: 1,
height,
},
});
Though it works, the question why do I need to set a height for an image in the same folder still stand.
if you want to give a value in percentage in such cases you should use some tricks like:
background:‌ {
height: deviceHeight,
},
container:‌ {
height: deviceHeight * 50 / 100,
}
or you can use a popular library in the name of react-native-responsive-screen. This library is going to give you the power to give relative values and convert them to absolute values behind the scene.
The snippet below is going to show how to use it:
import {widthPercentageToDP, heightPercentageToDP} from 'react-native-responsive-screen';
const styles = StyleSheet.create({
background:‌ {
height: heightPercentageToDP('100%'),
}
})
This should work as you expected ;)
If you want your background image to cover your entire view, try something like this:
<View>
<ImageBackground style={styles.image} resizeMode={'cover'} source={require('../Images/test.jpg')}>
{/*your components*/}
</ImageBackground>
</View>
with this styling:
const styles = StyleSheet.create({
image: {
height: '100%',
width: undefined,
}
})

How do I display a random image retrieved from an array in react native

I am trying to randomly display images from a local file that have been stored in an array in a Card component which is then rendered in the App, the root of the application.
Here is the Images file containing an array of images in the same directory.
const woolyImages = [
require('images/wooly1'),
require('images/wooly2'),
require('images/wooly3'),
require('images/wooly4'),
require('images/wooly5'),
];
export default woolyImages;
Here is the Card component where I attempt to pick a random image from the array and display it using the Image component via 'source'.
import React from 'react';
import {Image, View, StyleSheet} from 'react-native';
import woolyImages from '../images/Images';
function Card() {
const randomImage =
woolyImages[Math.floor(Math.random() * woolyImages.length)];
console.log(randomImage);
return (
<View style={styles.cardContainer}>
<Image source={randomImage} />
</View>
);
}
const styles = StyleSheet.create({
cardContainer: {
width: '50%',
height: '35%',
backgroundColor: 'pink',
},
});
export default Card;
(I inserted the pink background so I could be sure it was rendering in the view. It is.)
Finally, here is the root of the application where I render the card.
import React from 'react';
import {View, StyleSheet} from 'react-native';
import Header from './components/Header';
import Card from './components/Card';
import GenerateWoolyButton from './components/GenerateWoolyButton';
function App() {
return (
<View style={styles.container}>
<Header />
<Card />
<GenerateWoolyButton style={styles.button} />
</View>
);
}
const styles = StyleSheet.create({
container: {
justifyContent: 'flex-start',
alignItems: 'center',
flex: 1,
},
});
export default App;
I am getting the below error.
Can anyone please tell me how to display a randomly generated picture in the Card component and display it in the root of my application? Thank you.
You need to add width & height styles to Image of your Card Component. Such as,
<Image source={randomImage} style={{height: 200, width: 200}} />
Hope this will helps you. Feel free for doubts.

React Native UI Component Wrap in Touchable

I'm trying to detect when a user presses on a custom UI component I have written (it displays a video feed). I've tried using all the touchable components, and would ideally want to use the TouchableWithoutFeedback component, but none of them detect presses on my component. Additionally, when I select my component with the inspector, I get the error Expected to find at least one React renderer but I'm not sure how to set up my component correctly to have a renderer.
The native UI component:
public class DroneVideoFeedManager extends SimpleViewManager<DroneVideoFeed> {
#Override
public String getName() {
return "DroneLiveVideo";
}
#Override
public DroneVideoFeed createViewInstance(ThemedReactContext context) {
return new DroneVideoFeed(context, null);
}
}
My UI component Javascript wrapper is as follows:
import PropTypes from 'prop-types';
import {
requireNativeComponent,
ViewPropTypes,
} from 'react-native';
const iface = {
name: 'DroneLiveVideo',
propTypes: {
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
...ViewPropTypes, // include the default view properties
},
};
module.exports = requireNativeComponent('DroneLiveVideo', iface);
And my attempt to detect a press:
<TouchableWithoutFeedback
onPress={() => console.log('pressed!')}
>
<DroneLiveView
style={{
width: '100%',
height: '100%',
}}
/>
</TouchableWithoutFeedback>
This is the first time I have attempted to implement a native UI component in React Native, so apologies in advance if I am doing things incorrectly.
I found a solution, it's perhaps a little convoluted and not the best way of doing things but it works!
I changed my javascript wrapper to return a view with my native UI component, and another view above it (using absolute positioning). This view appears to handle touches and allows touchables to work with my component.
My changed UI component wrapper is as follows:
import React, {
Component,
} from 'react';
import {
requireNativeComponent,
View,
} from 'react-native';
class DroneVideo extends Component<{}> {
constructor(props) {
super(props);
}
render() {
return (
<View
{...this.props}
>
<View
style={{
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 2,
}}
></View>
<DroneVideoNative
style={{
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 1,
}}
/>
</View>
);
}
}
let DroneVideoNative = requireNativeComponent('DroneLiveVideo', DroneVideo);
export default DroneVideo;