Friends, I would like to overlay a button on a webview in react native to redirect routes manually.
The react native buttons should be invisible on top of the webview buttons
The following image shows the buttons on the web page and below the react native buttons.
1
another problem is that the keyboard does not open when clicking on an input within the webview
here's my code:
const App = () => {
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width
const [url, setUrl] = useState('https://rootroute.com.br/');
return (
<KeyboardAvoidingView
behavior={ Platform.OS === 'ios' ? 'padding' : undefined }
style={styles.keyboardAvoidingView}
>
<View style={{ flex: 1}}>
<WebView
source={{ uri: url }}
onError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
Alert.alert('WebView error: ', "" + nativeEvent);
}}
onHttpError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
console.warn(
'WebView received error status code: ',
nativeEvent.statusCode,
);
}}
mixedContentMode={'always'}
geolocationEnabled={true}
ignoreSslError={true}
javaScriptEnabled={true}
domStorageEnabled={true}
scalesPageToFit={true}
startInLoadingState={false}
style={{ flex: 1, width: deviceWidth, height: deviceHeight, marginTop: 15 }}
/>
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/1')}
title="Home"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/2')}
title="Alerta"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/3')}
title="Explore"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/4')}
title="Carrinho"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/5')}
title="Conta"
/>
</View>
</View>
</View>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 50
},
buttonContainer: {
flex: 1,
},
keyboardAvoidingView: { flexGrow: 1, flexShrink: 1 },
});
export default App; ```
I think you don't need KeyboardAvoidingView in your case
Just use WebView and View
Because KeyboardAvoidingView use to handle TextInput keyboard on normal View
Related
The modal Stack.Screen is behaving differently on iOS and Android. On iOS modal is covering the full screen, but on Android not. I would like to have a static header with some UI (burger etc.), that is present in all screens and I don't want to animate the same UI as Stack.Screen header every time I change the screen. To achieve this I have added a static header outside Stack.Navigator. Everything works as expected apart from modal screen. When I initialise modal screen I expect it to cover the whole screen - also the static header. That is true for iOS. However on Android the static header component is not covered. I guess it is due to the fact that my static header "lives" outside Stack.Navigator.
I have created snack, so check it out https://snack.expo.dev/#fjckls/fullscreen-modal-android-issue
How to implement the desired behaviour with static header? Thanks!
const Contacts = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Contacts</Text>
<Button title="Show Modal" onPress={() => navigation.navigate('Modal')} />
</View>
);
};
const About = () => {
return (
<View style={{ flex: 1 }}>
<Text>About</Text>
</View>
);
};
const Modal = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>This is fullscreen modal!!!</Text>
</View>
);
};
const MyStaticHeader = () => {
return (
<View style={{ height: 60, justifyContent: 'center', alignItems: 'center', backgroundColor:'orange' }}>
<Text>MY STATIC HEADER!!</Text>
</View>
);
};
const TopTab = createMaterialTopTabNavigator();
const HomeTabs = () => {
return (
<TopTab.Navigator>
<TopTab.Screen name="Contacts" component={Contacts} />
<TopTab.Screen name="About" component={About} />
</TopTab.Navigator>
);
};
const Stack = createNativeStackNavigator();
const App = () => {
return (
<SafeAreaView style={{ flex: 1, justifyContent: 'center' }}>
<StatusBar animated={true} backgroundColor="#61dafb" />
<MyStaticHeader />
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={HomeTabs} />
<Stack.Screen
name="Modal"
component={Modal}
options={{ presentation: 'modal',animation: 'slide_from_bottom' }}
/>
</Stack.Navigator>
</NavigationContainer>
</SafeAreaView>
);
};
I would like use DrawerLayoutAndroid module on React-Native app. For use openDrawer programmaticaly, i use useRef hook.
On run this method, my Drawer show only black "overflow", but not the navigation.
If i swip to the right, my Drawler menu will be show :/
My code :
const Layout = ({ children }) => {
let drawler = useRef(null);
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
ref={drawler}
renderNavigationView={() => (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<Text style={{ margin: 10, fontSize: 15, textAlign: 'left' }}>
I'm in the Drawer!
</Text>
</View>
)}>
<View style={{ flex: 1 }}>
<ScrollView>
<View style={styles.container}>
<Button onPress={() => drawler.current.openDrawer()}> // Show only overflow, not the menu
Open drawler
</Button>
{children}
</View>
</ScrollView>
</View>
</DrawerLayoutAndroid>
);
};
Anyone can help me ?
I solved the issue with useCallback
const [drawer, setDrawer] = useState();
const refDrawer = useCallback(element => {
setDrawer(element);
}, []);
Don't forget set ref={refDrawer} attribute to the DrawerLayoutAndroid component.
Here this is my app.js
const AppStackNavigator = createStackNavigator({
Login:{ screen: Login },
DrawerNav: { screen: DrawerNavigator },
})
class App extends React.Component{
render() {
return (
<AppStackNavigator/>
)
}
}
export default createAppContainer(AppStackNavigator);
And this is DrawerNavigator.js file
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Header>
<Left>
<Icon name = "menu" onPress={() => this.props.navigation.openDrawer()}/>
</Left>
</Header>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle Drawer"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
);
}
}
const CustomDrawerComponent = (props)=>(
<SafeAreaView>
<View style={{height:150, backgroundColor:'white', alignItems:'center', justifyContent:'center'}}>
<Image source={require('./logo.png')} style={{height:120, width:120, borderRadius:60}} />
</View>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView> )
const navigator = createDrawerNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {drawerLabel: 'HomeScreen',}
},
SettingsScreen: {
screen: SettingsScreen,
navigationOptions: {drawerLabel: 'SettingsScreen',}
}},
{
drawerPosition :"left", contentComponent:CustomDrawerComponent
});
export default createAppContainer(navigator);
And this is login.js
class Login extends React.Component{
constructor(props){
super(props);
}
static navigationOptions = {
title:'Welcome',
headerLeft:
<View style={{paddingLeft:16}}>
<Icon
name="md-menu"
size={30}
color='black'
onPress={() => this.props.navigation.openDrawer()} />
</View>
}
loginHandler= ()=>{
//this.props.navigation.navigate('DrawerNav')
this.props.navigation.openDrawer()
}
render(){
return(
<View style={styles.container}>
<View style={{alignItems:'center'}}>
<Button
title={'Login'}
onPress={this.loginHandler.bind(this)}/>
</View>
</View>
)
}
}
export default Login;
Now Whenever i click icon to open navigation drawer then error arises undefined is not an object (evaluating _this2.props.navigation).I have tried many possible ways but i couldnt solve this problem.How can i solve this ? I have registered login component inside stack navigator then also login component was not able access navigation props.
onPress={() => this.props.navigation.openDrawer()}
Error describes that this line inside static block in login.js contains error
I'm trying to implement a drawer menu in react native and I'm not sure if I'm doing it right. Here is what I have so far:
#App.js
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
Save: SaveScreen,
About: AboutScreen,
},
{
initialRouteName: 'Home',
}
);
#Homescreen.js
static navigationOptions = {
// headerTitle instead of title
drawerLabel: 'Home',
headerTitle:
<View style={{flex: 1, flexDirection: 'row', marginLeft: 16}}>
<TouchableOpacity style={styles.button} onPress={()=>{this.props.navigation.openDrawer()}}>
<Image
source={require('../../assets/ic-hamburger.png')}
style={{ width: 20, height: 18 }}
/>
</TouchableOpacity>
<Text style={styles.menuTitle}>Menu</Text>
</View>
};
How come this.props.navigation is undefined here? How do I retrieve it so that the drawer opens when the image is clicked?
Thanks !
Try this using the navigation object:
static navigationOptions = ({ navigation }) => ({
// headerTitle instead of title
drawerLabel: 'Home',
headerTitle:
<View style={{flex: 1, flexDirection: 'row', marginLeft: 16}}>
<TouchableOpacity style={styles.button} onPress={()=>navigation.navigate('DrawerOpen')}>
....
</TouchableOpacity>
</View>
});
I am a beginner at React Native. As you can see from the image that I have a Scroll View and two buttons. I have successfully implemented the scroll View which works fine but I also want to them to auto scroll on the press of a button. I have tried searching a lot but not getting anything which is working. So any help is appreciated. Please find my code below.
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Dimensions, ScrollView, Button } from 'react-native';
var screenWidth = Dimensions.get('window').width;
export default class App extends React.Component {
render() {
return (
<View style={styles.MainContainer}>
<View style={styles.ButtonViewContainer}>
<View style={styles.ButtonContainer}>
<Button title="Screen 1" />
</View>
<View style={styles.ButtonContainer}>
<Button title="Screen 2" />
</View>
</View>
<ScrollView
horizontal={true}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
>
<View style={styles.ScrollContainer}>
<Text style={styles.ScrollTextContainer}>
Screen 1
</Text>
</View>
<View style={styles.ScrollContainer}>
<Text style={styles.ScrollTextContainer}>
Screen 2
</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer: {
backgroundColor: '#abe3a8',
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
ScrollContainer: {
backgroundColor: '#cdf1ec',
flexGrow: 1,
marginTop: 0,
width: screenWidth,
justifyContent: 'center',
alignItems: 'center'
},
ScrollTextContainer: {
fontSize: 20,
padding: 15,
color: '#000',
textAlign: 'center'
},
ButtonViewContainer: {
flexDirection: 'row',
paddingTop: 35,
},
ButtonContainer: {
padding: 30,
},
});
I cant gurantee this is the best approach as I havent worked alot with React Native.
Add this.scroll.scrollTo({ x: calculatedStartPositionOfTheScreen}) to your button Press handler
https://facebook.github.io/react-native/docs/scrollview#scrollto
e.g
<View>
...
<View style={styles.ButtonContainer}>
<Button title="Screen 1" onPress={() => { this.scroll.scrollTo({ x: 0 }) }} />
</View>
<View style={styles.ButtonContainer}>
<Button title="Screen 2" onPress={() => { this.scroll.scrollTo({ x: screenWidth }) }} />
</View>
<View style={styles.ButtonContainer}>
<Button title="Screen 3" onPress={() => { this.scroll.scrollTo({ x: screenWidth * 2 }) }} />
</View>
...
<ScrollView
horizontal={true}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
ref={(node) => this.scroll = node}
>
...
</ScrollView>
</View >
For this use case in bigger projects you can also consider
https://reactnavigation.org
Try this.
<View>
...
<View style={styles.ButtonContainer}>
<Button title="Screen 1" onPress={() => { this.refs.scroll.scrollTo({ x: 0 }) }} />
</View>
<View style={styles.ButtonContainer}>
<Button title="Screen 2" onPress={() => { this.refs.scroll.scrollTo({ x: screenWidth }) }} />
</View>
<View style={styles.ButtonContainer}>
<Button title="Screen 3" onPress={() => { this.refs.scroll.scrollTo({ x: screenWidth * 2 }) }} />
</View>
...
<ScrollView
horizontal={true}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
ref={'scroll'}
>
...
</ScrollView>
</View >
You can try:
onPress = (index) => {
this.scroll.scrollTo({x: index * screenWidth, y: 0, animated: true})
}
<Button title="Screen 1"
onPress = {() => this.onPress(0)}
/>
...
<Button title="Screen 2"
onPress = {() => this.onPress(1)}
/>
...
<ScrollView
horizontal={true}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
ref = {re => this.scroll = re}
>
</ScrollView>