How can i make DrawerLayout reusable? - android

I am new to ReactNavite. I am playing around with Android DrawerLayout.
I am using StackNavigator for screen redirection.
Do I have to put DrawerLayoutAndroid in each screen, because it does not seem logical? Can't I create a custom class and use it in every screen and some property like selected or unselected?
Screen1.js
export default class Screen1 extends Component<{}> {
static navigationOptions = {
header: null
};
onScreen1Click() {
this.refs["NAVDRAWER"].closeDrawer();
this.props.navigation.navigate("screen1");
}
onScreen2Click() {
this.refs["NAVDRAWER"].closeDrawer();
this.props.navigation.navigate("screen2");
}
render() {
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => {
return (
<ScrollView vertical={true}>
<View style={styles.drawerMenuSelectedView}>
<Text
style={styles.menuItemSelected}
onPress={() => this.onScreen1Click()}
>
Screen 1
</Text>
</View>
<View style={styles.drawerMenuUnselectedView}>
<Text
style={styles.menuItemUnselected}
onPress={() => this.onScreen2Click()}
>
Screen 2
</Text>
</View>
</ScrollView>
);
}}
ref={"NAVDRAWER"}
>
<View>
<Text> Screen 1 </Text>
</View>
</DrawerLayoutAndroid>
); }
}
Screen2.js
export default class Screen2 extends Component<{}> {
static navigationOptions = {
header: null
};
onScreen1Click() {
this.refs["NAVDRAWER"].closeDrawer();
this.props.navigation.navigate("screen1");
}
onScreen2Click() {
this.refs["NAVDRAWER"].closeDrawer();
this.props.navigation.navigate("screen2");
}
render() {
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => {
return (
<ScrollView vertical={true}>
<View style={styles.drawerMenuSelectedView}>
<Text
style={styles.menuItemUnselected}
onPress={() => this.onScreen1Click()}
>
Screen 1
</Text>
</View>
<View style={styles.drawerMenuUnselectedView}>
<Text
style={styles.menuItemSelected }
onPress={() => this.onScreen2Click()}
>
Screen 2
</Text>
</View>
</ScrollView>
);
}}
ref={"NAVDRAWER"}
>
<View>
<Text> Screen 2 </Text>
</View>
</DrawerLayoutAndroid>
); }
}
App.js
import React, { Component } from 'react';
import { StackNavigator } from "react-navigation";
import Screen1 from "./Screen1";
import Screen2 from "./Screen2";
export default class App extends Component<Props> {
render() {
return (
<MyApp />
);
}
}
const MyApp = StackNavigator({
screen1: { screen: Screen1 },
screen2: { screen: Screen2 },
});

After long time researching , I landed on this library for drawer navigation with reusable Drawer,
https://github.com/react-navigation/react-navigation
This lib provides DrawerNavigator , Which also helps us to make custom Drawer Design and you can add screens of Drawer in DrawerNavigator...
Also, I have used this blog for reference
https://codeburst.io/custom-drawer-using-react-navigation-80abbab489f7
I hope this helps you ...

Related

Open screen is not working with the line below

I have one component, he open a modal...
App.js
import ScreenModal from './ScreenModal';
return (
<View>
<TouchableOpacity onPress={ScreenModal}>
<Text>Click</Text>
</TouchableOpacity>
</View>
);
ScreenModal.js
function getModal() {
return (
<Modal isVisible={true}>
<Text>Teste</Text>
</Modal>
)
}
He not open a modal (ScreenModal). where it is the error?
obs.: I have a custom modal
your code should be like this
//your modal component
const MyModalComponent = ({isVisible = true}) => {
return (
<Modal visible={isVisible}>
<Text>Teste</Text>
</Modal>
)
}
and use it like that
const App = () => {
const [isVisible, setVisible] = React.useState(false);
return(
<View>
<TouchableOpacity onPress={() => setVisible(true)}>
<Text>Click</Text>
</TouchableOpacity>
<MyModalComponent isVisible={isVisible} />
</View>
)
}
see docs example here

React Native - How to get picker data

I am new to React Native. If I asked something so easy sorry 'bout that.
I have Picker Component in my App.js.
I want to go to component depending on a Picker item.
So, for example; I picked the second item of Picker, when I Clicked the 'Next' button it has to go to second.js
Here is some Part of my Code:
My App.js:
...
...
function Third({ navigation }) {
return (
<View style={styles.container}>
<Text style={styles.circle}>2</Text><Text style={styles.titles}>Operating Mode</Text>
<Text />
<Text style={styles.description}>Please select operating mode</Text><Text/>
<Picker/>
<Button title="Next" style={styles.buttons} color="#FF7F11" onPress={() => navigation.navigate("Fourth")}/><Text/>
<Button title="Back" style={styles.buttons} color="#FF7F11" onPress={() => navigation.goBack()} /><Text/>
</View>
);
}
...
...
and my Picker.js:
import React, { Component } from "react";
import { Text, View, StyleSheet } from "react-native";
import { Picker } from "#react-native-picker/picker";
class Picker extends Component {
state = {router: ''}
updaterouter = (router) => {
this.setState({ router: router })
}
render() {
return (
<View>
<Picker selectedValue={this.state.router} style={styles.drop} onValueChange = {this.updaterouter}>
<Picker.Item label="Rt" value="rt" />
<Picker.Item label="Ap" value="ap" />
<Picker.Item label="Rp" value="rp" />
<Picker.Item label="Wp" value="wp" />
</Picker><Text></Text>
</View>
);
}
}
export default Picker
const styles = StyleSheet.create({
drop: {
height: 30,
width: 200,
backgroundColor: "#FFF"
}
})
One option is to pass the value to the parent via a callback function, something like this:
updaterouter = (router) => {
this.setState({ router: router })
props.onRouterUpdated && props.onRouterUpdated(router)
}
<Picker onRouterUpdated={(r)=>{/*do something with r*/}}/>
Another would be to use common store (e.g. Redux)

How to get variable react native

I'm using react native expo for the following project basically i want to retrive the selected item form an flat list and display it in a modal
import React,{ Component}from 'react';
import {View,Text,Image,StyleSheet,Modal,Button} from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
export default class MealSearch extends Component{
constructor(props){
super(props)
this.state = {
loaded:false,
show:false,
key:''
}}
render(){
const meal= [ {title:'My hero Academia',img:{uri:'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png'}, body:'Rating : 4.5/5' , id :'1'},
{title:'Naruto',img:{uri:'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF'}, body:'Rating : 5/5' , id :'2'},
{title:'Attack On Titan',img:{uri:'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380'}, body:'Rating : 4.5/5' , id :'3'},
{title:'Fate: Unlimited Blade Works',img:{uri:'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg'}, body:'Rating : 4.5/5' , id :'4'}
]
const handlePress = (meal_data) =>{
this.setState({show: true});
this.setState({selectedMeal:meal_data});
console.log(meal_data)
}
return(
<View style={styles.view} >
<FlatList
keyExtractor={item => item.id}
data={meal}
renderItem={({item})=>(
<Card>
<TouchableOpacity onPress={(_item)=>{handlePress(item)}}>
<View style={styles.mealItem}>
<Image style={{width:300,height:150}} resizeMode={'contain'} source={item.img} marginLeft={30}/>
<View style={styles.descrip}>
<Text style={styles.rating}>{item.title}</Text>
<Text style={styles.name}>{item.body}</Text>
</View>
</View>
</TouchableOpacity>
</Card>
)}
/>
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={()=>{this.setState({show:false})}}/>
</View>
</View>
</Modal>
</View>
);}
}
this is the code I'm currently working on I want the 'meal_data' in 'handlePress' to be displayed inside my modal 'meal_data' is the selected item from the flat list .
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={()=>{this.setState({show:false})}}/>
</View>
</View>
</Modal>
I want to display it in here above the button
Change these lines of code:
Change: <TouchableOpacity onPress={(_item)=>{handlePress(item)}}>
To
<TouchableOpacity onPress={() => this.handlePress(item)}>
Delete this code inside render():
const handlePress = (meal_data) =>{
this.setState({show: true});
this.setState({selectedMeal:meal_data});
console.log(meal_data)
}
And put this code above render() medthod instead:
handlePress = (meal_data) =>{
this.setState({show: true, selectedMeal: meal_data});
console.log(meal_data)
}
Inside state
this.state = {
loaded:false,
show:false,
key:''
selectedMeal: null // Add this property
}}
After that, you'll be able to access selectedMeal inside your Modal.
Put this code inside the Modal (or somewhere else)
{this.state.selectedMeal && (
<View>
<Text>{this.state.selectedMeal.title}</Text>
</View>
)}
First of declare your handlePress outside of render method. Other thing is that this.setState() is Async so, first set you data then show the modal. Your final code should look like this :
import React, { Component } from 'react';
import { View, Text, Image, StyleSheet, Modal, Button } from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
export default class MealSearch extends Component {
constructor(props) {
super(props)
this.state = {
loaded: false,
show: false,
key: ''
}
}
handlePress = (meal_data) => {
this.setState({ selectedMeal: meal_data }, () => {
this.setState({ show: true });
});
console.log(meal_data)
}
render() {
const meal = [
{ title: 'My hero Academia', img: { uri: 'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png' }, body: 'Rating : 4.5/5', id: '1' },
{ title: 'Naruto', img: { uri: 'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF' }, body: 'Rating : 5/5', id: '2' },
{ title: 'Attack On Titan', img: { uri: 'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380' }, body: 'Rating : 4.5/5', id: '3' },
{ title: 'Fate: Unlimited Blade Works', img: { uri: 'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg' }, body: 'Rating : 4.5/5', id: '4' }
]
return (
<View style={styles.view} >
<FlatList
keyExtractor={item => item.id}
data={meal}
renderItem={({ item }) => (
<Card>
<TouchableOpacity onPress={() => { this.handlePress(item) }}>
<View style={styles.mealItem}>
<Image style={{ width: 300, height: 150 }} resizeMode={'contain'} source={item.img} marginLeft={30} />
<View style={styles.descrip}>
<Text style={styles.rating}>{item.title}</Text>
<Text style={styles.name}>{item.body}</Text>
</View>
</View>
</TouchableOpacity>
</Card>
)}
/>
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={() => { this.setState({ show: false }) }} />
</View>
</View>
</Modal>
</View>
);
}
}

react native navigate to screen from function

I'm trying to move through screens using React Navigation, the problem lies in the nested return that i use to dynamically render a set of items and doesn't let me use an arrow function to directly navigate, so i have to implement this on a function. My question here is, how do i do that? As far as my internet research went you can only push a new screen after a dialog alert shows up, i don't want that.
I'm attaching the code:
var Dimensions = require('Dimensions');
var {width,height} = Dimensions.get('window');
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Image
} from 'react-native';
import Pie from 'react-native-pie';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import NaviBarView from './../Commons/NaviBar'
import actions from '../../Redux/actions'
class Main extends Component {
constructor(props){
super(props);
this.state={
cargando:true,
cryptoCurrencyValues:{}
}
this.onNextPress = this.onNextPress.bind(this);
this.renderItems = this.renderItems.bind(this);
}
static getDerivedStateFromProps(nextProps,prevState){
console.warn('Positivo', Object.keys(nextProps.cryptoCurrencyValues).length)
if (Object.keys(nextProps.cryptoCurrencyValues).length !== 0){
}else{
console.warn('Negativo')
}
return null;
}
onNextPress(){
**//HERE I WANT TO CALL NAVIGATE TO MOVE TO ANOTHER SCREEN**
}
componentDidMount(){
console.warn('esto una vez')
this.props.actions.getCryptoValues();
this.setState({cargando:true})
}
renderItems(){
var self = this;
return listData.map(function(cryptoValue,i){
return(
<View style={styles.itemContainer} key={i}>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:10}}>
<Image source={cryptoValue.img} style={{width:width*0.095, height:height*0.050}} resizeMode={'stretch'}/>
</View>
<View style={{marginLeft:10}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18,fontWeight: 'bold'}}>{cryptoValue.name}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.desc}</Text>
</View>
</View>
<View style={{marginLeft:40}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18}}>{cryptoValue.price}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.currency}</Text>
</View>
</View>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:50}}>
<TouchableOpacity onPress={() => self.onNextPress()} style={{alignSelf:'center',backgroundColor:'transparent'}}>
<Image source={require('./../../img/next.png')} style={{width:width*0.035, height:height*0.032}} resizeMode={'stretch'}/>
</TouchableOpacity>
</View>
</View>
);
});
}
render(){
return(
<View style={styles.container}>
<View>
<NaviBarView/>
</View>
<View style={styles.cardContainer}>
<View style={{marginTop:10,flexDirection: 'row',marginTop:10,marginLeft:10,alignItems:'stretch'}}>
<Image source={require('./../../img/pie-chart.png')} resizeMode={'stretch'} style={{width:width*0.095, height:height*0.055}}/>
<Text style={{fontSize:20,color:'#ffffff',fontWeight:'bold',marginLeft:15,alignSelf:'center'}}>STATUS</Text>
<TouchableOpacity style={{marginLeft:230,alignSelf:'center'}}>
<Image source={require('./../../img/reload.png')} resizeMode={'stretch'} style={{width:width*0.065, height:height*0.035}}/>
</TouchableOpacity>
</View>
<View style={{alignSelf:'flex-start',marginTop:50}}>
<Pie
radius={100}
innerRadius={97}
series={[10, 20, 30, 40]}
colors={['#f00', '#0f0', '#00f', '#ff0']}
/>
</View>
</View>
{this.renderItems()}
</View>
);
}
}
const listData = [
{_id:1,name:'Bitcoin',desc:'Billetera BTC',price:'$141,403.22',currency:'BTC: $11.673,50',img:require('./../../img/bitcoin.png')},
{_id:2,name:'Ethereum',desc:'Billetera ETH',price:'$20200,50',currency:'ETH: $863,40',img:require('./../../img/ethereum.png')},
{_id:3,name:'NEO',desc:'Billetera NEO',price:'$40.401',currency:'NEO: $118,02',img:require('./../../img/neo.png')},
];
const styles = new StyleSheet.create({
container:{
flex:1,
backgroundColor: '#0d0d0d',
flexDirection: 'column',
position:'relative',
},
cardContainer:{
backgroundColor:'#1a1a1a',
marginTop: 7,
marginBottom:7,
marginLeft:7,
marginRight:7,
height:height*0.50,
width:width,
justifyContent: 'flex-start'
},
itemContainer:{
flexDirection: 'row',
backgroundColor:'#1a1a1a',
width:width,
height:height*0.115,
marginLeft:7,
marginRight:7,
marginBottom:7,
justifyContent: 'flex-start'
},
})
function mapStateToProps (state,props) {
return {cryptoCurrencyValues: state.cryptocurrencyValues,
}
}
function mapDispatchToProps (dispatch) {
return {
actions: bindActionCreators(actions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use Stack Navigator here which is very easy to navigate from one screen to another and as well as in function too...
First.
Install library :-
npm install --save react-navigation
Then use it in your class by using import :-
import {StackNavigator} from 'react-navigation';
export that class
export default Project = StackNavigator(
{
xyz: { screen: xyz },
});
After that navigating using function:-
onNextPress=()=>
{
this.props.navigation.navigate('xyz');
}
Hope.it will helps you .
Thanx!
I was not passing the navigation prop when defining my RootStack:
import React, {Component} from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';
import createStore from './../../Redux/store';
import {StackNavigator} from 'react-navigation';
import { Provider } from 'react-redux';
import MainView from '../Main/Main';
import MainSecondLvlView from '../Main/MainSecondLvl';
import BalanceView from './../Charts/BalanceView'
import MenuView from './Menu'
const store = createStore();
const RootStack = StackNavigator({
Main: { screen: MainView },
MainSecondLvl: { screen: MainSecondLvlView},
Menu:{ screen: MenuView }
},
{
initialRouteName: 'Main',
headerMode: 'none',
});
export default class App extends Component {
render(){
return(
<Provider store={store}>
<RootStack navigation={this.props.navigation}/>
</Provider>
);
}
}

react-native-navigation showInAppNotification blank

Trying use this.props.navigator.showInAppNotification
this.props.navigator.showInAppNotification({
screen: "example.InAppNotification",
passProps: {
title: 'Title',
body: 'Body...'
},
position: 'bottom',
autoDismissTimerSec: 3
});
screen InAppNotification is registered, but see notification with blank content:
Can anyone help with this?
example.InAppNotification:
export default class InAppNotification extends Component {
render() {
console.log(this.props);
return (
<View>
<Text>
{JSON.stringify(this.props)}
</Text>
</View>
);
}
}
try by adding flex:1 to container View
export default class InAppNotification extends Component {
render() {
console.log(this.props);
return (
<View style={{ flex: 1 }}>
<Text>
{JSON.stringify(this.props)}
</Text>
</View>
);
}
}
also you need to register InAppNotification screen correctly

Categories

Resources