I am trying to use the react-native's ToolbarAndroid from react-native-vector-icons's Icon.ToolbarAndroid. But I am getting this error:
RNVectorIconsModule not available, did you properly integrate the module?
I have installed rnpm also did rnpm link, which was completed successfully.
And I think I have properly integrated the module, because this code works where I get the icons from react-native-vector-icons/Ionicons:
(WORKING)
import Icon from 'react-native-vector-icons/Ionicons';
const searchIcon = (<Icon name="md-search" size={30} color="#4F8EF7" />)
const menuIcon = (<Icon name="md-menu" size={30} color="#4F8EF7" />)
const notificationIcon = (<Icon name="md-notifications-outline" size={30} color="#4F8EF7" />)
export default class Header extends Component {
render() {
return(
<View>
<Text>{searchIcon}</Text>
<Text>{menuIcon}</Text>
<Text>{notificationIcon}</Text>
</View>
)
}
}
But this code doesn't work:
(NOT WORKING)
import Icon from 'react-native-vector-icons/Ionicons';
export default class Header extends Component {
render() {
return(
<Icon.ToolbarAndroid
title="Home"
titleColor="white"
navIconName="md-search"
actions={[
{ title: 'Settings', iconName: 'md-menu', iconSize: 30, show: 'always' },
{ title: 'Follow me on Twitter', iconName: 'md-notifications-outline', iconColor: "#4099FF", show: 'ifRoom' },
]}
overflowIconName="md-more"
/>
)
}
}
I am very new to react-native so I may be doing something wrong? Will you please help me figure it out. Thank you.
As you have probably seen (I also saw your message on Github), the complete instructions are here: https://github.com/oblador/react-native-vector-icons#integrating-library-for-getimagesource-and-toolbarandroid-support
I had the same issue as yours. By completing the instructions, I successfully manage to make it work.
I will not duplicate the instructions but to clarify:
1) Edit android/settings.gradle
2) Edit android/app/build.gradle
3) Edit your MainApplication.java
Related
I upgraded native-base library from 2.13.14 to 3.0.3 and wrapped my App.js content in NativeBaseProvider. Here is the error I got after doing this:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
--
My Code:
import React, {useEffect} from 'react';
import {I18nManager, ActivityIndicator} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {NativeBaseProvider, Container} from 'native-base';
import TrackPlayer from 'react-native-track-player';
import {PlayerContextProvider} from './contexts/PlayerContext';
import MainStackNavigator from './Navigators/MainStackNavigator';
const App = () => {
const [isReady, setIsReady] = React.useState(false);
useEffect(() => {
TrackPlayer.setupPlayer().then(() => {
console.log('player is setup');
TrackPlayer.updateOptions({
capabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE,
TrackPlayer.CAPABILITY_STOP,
TrackPlayer.CAPABILITY_JUMP_BACKWARD,
TrackPlayer.CAPABILITY_JUMP_FORWARD,
],
jumpInterval: 30,
});
setIsReady(true);
});
}, []);
return (
<NativeBaseProvider>
<Container>
{isReady ? (
<PlayerContextProvider>
<NavigationContainer>
<MainStackNavigator />
</NavigationContainer>
</PlayerContextProvider>
) : (
<Container>
<ActivityIndicator />
</Container>
)}
</Container>
</NativeBaseProvider>
);
};
I18nManager.forceRTL(true);
export default App;
I did found the root cause of this problem (in my case). The approach was to go down the navigator structure (in your case start with MainStackNavigator) and replace the rendered component with the example code from https://docs.nativebase.io/setup-provider until it breaks:
function Test() {
return (
<Box flex={1} bg="#fff" alignItems="center" justifyContent="center">
<Text>Open up App.js to start working on your app!</Text>
</Box>
)
}
In my case it lead me to a component which was using deprecated native-base elements from v2. Sadly there is no good deprecation guide or migration guide which tells you how to upgrade from v2 to v3.
So following this approach might lead out of this situation (the error message is not really helpful). Keep an eye on the following deprecated components or functions and replace them as follows:
Header -> use HStack docs.nativebase.io/3.0.0/migration/Header
Body -> use Box or Container (not documented)
Left -> use Center or remove (not documented)
Right -> use Center or remove (not documented)
getTheme -> use extendTheme docs.nativebase.io/setup-provider#add-custom-theme-optional
StyleProvider -> use NativeBaseProvider docs.nativebase.io/setup-provider
This is my list of deprecated components so far. In addition here are some update guides for
Icon docs.nativebase.io/3.0.0/migration/Icon
Button docs.nativebase.io/3.0.0/migration/Button
and there are a lot more to be found on this index page https://docs.nativebase.io/3.0.0/migration/
I hope It helps you solving this problem.
Have a try to move the forceRTL method inside the useEffect of the app initialization.
like :
useEffect(() => {
I18nManager.forceRTL(true); // here..
TrackPlayer.setupPlayer().then(() => {
Might it will help you.
I've been using the library to create bottom sheet modals for my react native app, but it's doesn't seem to work on Android, but on iOS it does. I used the same backdrop component and handle component suggested in the docs, and everything is contained is the provider, and SafeAreaView
my package.json includes
"#gorhom/bottom-sheet": "^3.6.5",
"react-native-reanimated": "^2.0.0",
and the code is structured like this:
<BottomSheetModal ref={reference_settings}
index = {1}
enableOverDrag={true}
onChange = {(index) => { if(index === 0) { reference_settings.current.dismiss(); } }}
snapPoints = {[-1, '50%', '70%']}
backdropComponent={Backdrop}
handleComponent ={(props) => (<Belt {...props} />)}
style ={styles.sheet}
>
<BottomSheetView style={[styles.content]}>
<View style={{ width, height: '100%', overflow: 'hidden', backgroundColor: scheme === 'dark' ? '#000' : '#FFF', paddingHorizontal: 10 }}>
// the functions inside
</View>
</BottomSheetView>
</BottomSheetModal>
I used the right configuration for babel for react-native-reanimated including the plugin, but it shows up and then I can't drag to close.
I know it's a bit late to answer for you but I would like to add for others. Assuming you already installed react-native-gesture-handler you should also add some lines of code to your MainActivity.java.
Don't forget to wrap your Root App Component like this in the index.js file
place the the import statement at the top of index.js
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import {AppRegistry} from 'react-native';
AppRegistry.registerComponent(appName, () => gestureHandlerRootHOC(App));
more details
My react-native app look totally fine on most Android devices (and iOS) I tested on emulator, but some devices with noticeable curved screen on top (Google Pixel 4, API 29), it shows a big empty region on top of the phone.
This does not look normal. Do you know how to fix it ?
I am using SafeAreaView but without any Android specific padding/margin.
<SafeAreaView style={{flex:1}}>
... My App Code come here.
</SafeAreaView>
I also tried to remove the the SafeAreaView and used regular View instead but it still wont go away.
Just for testing I removed everything and added a hello world test screen.
It still gives same wide empty space.
My App.js:
export default class Main extends React.Component {
constructor(props) {
super (props);
}
render () {
return (
<View style={{flex:1, backgroundColor: 'white'}}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
AppRegistry.registerComponent(appName, () => Main);
You can't remove it, it's a display bug on the Pixel 4 emulator. A physical Pixel 4 doesn't have that gap.
See my other answer for a detailed explanation.
You can achieve this simply by hiding your StatusBar just like this:
import React from "react";
import { StatusBar, View, Text } from "react-native";
export default class Main extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
StatusBar.setHidden(true);
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
Update: set StatusBar's transluent attribute to true along with make its' background as transparent like this:
import React, { Component } from "react";
import { StatusBar, View, Text } from "react-native";
export default class Main extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
StatusBar.setTranslucent(true);
StatusBar.setBackgroundColor("transparent");
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
Have you tried using this way
<StatusBar translucent={true} hidden={true} /> {/* <--- Here */}
Check statusbar component where you can draw an app under the status bar by using the property named translucent. Reference link
I managed to fix this by going to AVD Manager -> Click on Wipe Data
Img
When I am using Navigator from react native I am getting an error. The error is:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check your code at App.js:11.
My code is:
import React, { Component } from 'react';
import {
Text,
Navigator,
TouchableHighlight
} from 'react-native';
export default class App extends Component {
render() {
return (
<Navigator
initialRoute={{ title: 'Awesome Scene', index: 0 }}
renderScene={(route, navigator) => (
<Text>Hello {route.title}!</Text>
)}
style={{ padding: 100 }}
/>
);
}
}
I followed this tutorial: https://reactnative.dev/docs/0.43/navigator
Can someone please help me in this. Is there something wrong in documentation?
This code example is from react doc version 0.43. After that "Navigator" was removed.
If you do not care about backward compatibility then I would suggest following current documentation (0.63). In the latest version, there is more simple solution is given.
I am trying to build an auth flow that has a welcome page and then login or signup depending on the user's case.
It is built inside a stack navigator. The first screen has no header but then login and signup do via their screen options.
// AuthNavigator
const AuthStackNavigator = createStackNavigator();
export const AuthNavigator = () => {
return (
<AuthStackNavigator.Navigator
initialRouteName={WELCOME_PAGE.id}
screenOptions={{
headerShown: false,
headerTintColor: colors.primary,
}}
lazy>
<AuthStackNavigator.Screen
name={WELCOME_PAGE.id}
component={WELCOME_PAGE.component}
/>
<AuthStackNavigator.Screen
name={LOGIN_PAGE.id}
component={LOGIN_PAGE.component}
options={LOGIN_PAGE.options}
/>
<AuthStackNavigator.Screen
name={SIGN_UP_PAGE.id}
component={SIGN_UP_PAGE.component}
options={LOGIN_PAGE.options}
/>
</AuthStackNavigator.Navigator>
);
};
This flow, is nested inside a tabNavigator:
// AuthTabNavigator
const AuthTabNavigator =
Platform.OS === 'android'
? createMaterialBottomTabNavigator()
: createBottomTabNavigator();
const RootNavigator = () => {
return (
<AuthTabNavigator.Navigator
activeColor={colors.primary}
inactiveColor="grey"
barStyle={materialBottomNavBackgroundColor}
tabBarOptions={defaultTabNavOptions}>
<AuthTabNavigator.Screen
name={WELCOME_PAGE.id}
component={AuthNavigator}
options={WELCOME_PAGE.options}
/>
</AuthTabNavigator.Navigator>
);
};
export default RootNavigator;
On iOS, things work fine but on Android, It has weird behaviour. When pressing on the input field, the keyboard pushes the bottom bar causing a clunky effect on press but also on dismiss of the field. As if it were recalculating the height every time and repositioning the layout.
In order to make sure it's not coming from my code, I tested again with the snippet from the React Native documentation
I get the following (these are on the Android emulator but I get the same result on my OnePlus android phone)
base version: https://recordit.co/tcEwDbo1oT
no header version: https://recordit.co/O4lZ9G83vg
not nested in a tab navigator: https://recordit.co/uh7mOGlKdk
The only version that works is the one when not nested in the tab navigator so I guess the issue comes from there.
I checked a few solutions but none worked:
Android manifest
Issue coming from the header
Another
workaround because of header
I am using React Native CLI:
"react-native": "0.62.2",
"#react-navigation/bottom-tabs": "^5.2.8",
"#react-navigation/drawer": "^5.7.2",
"#react-navigation/material-bottom-tabs": "^5.1.10",
"#react-navigation/native": "^5.1.7",
"#react-navigation/stack": "^5.2.17",
Let me know if you encountered the same issue and found a way to fix it. Thanks in advance.
EDIT: SOLUTION I WENT WITH
On top of the "custom" solution I posted in the comments, after opening an issue on React Navigation repo and checking closed issues, I found that on Android, you might have 2 options:
Either your invert the nesting, see here
Or you can set the behaviour of the keyboardAvoidingView to position on Android and provide a custom Tabbar
https://github.com/react-navigation/react-navigation/issues/7359#issuecomment-545842090
https://stackoverflow.com/a/51169574/11287266
I ended up going with the latter:
const TabBarComponent = props => {
return (
<View collapsable={false}>
<BottomTabBar {...props} />
</View>
);
};
// AuthTabNavigator
const AuthTabNavigator = createBottomTabNavigator();
const RootNavigator = () => {
return (
<AuthTabNavigator.Navigator
activeColor={colors.primary}
inactiveColor="grey"
barStyle={materialBottomNavBackgroundColor}
tabBarOptions={defaultTabNavOptions}
tabBar={props => <TabBarComponent {...props} />}>
<AuthTabNavigator.Screen
name={WELCOME_PAGE.id}
component={AuthNavigator}
options={WELCOME_PAGE.options}
/>
</AuthTabNavigator.Navigator>
);
};
export default RootNavigator;
<KeyboardAvoidingView
contentContainerStyle={{ flexGrow: 1 }}
style={styles.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'position'}
keyboardVerticalOffset={Platform.OS === 'android' ? -50 : 25}>