I am new to React-Native and love it so far. I am trying to create a screen (for the cross-platform app) with a menu icon on top right and when clicked, I want to open a men
react-native-modal-dropdown implement these things
+import ModalDropdown from 'react-native-modal-dropdown';
class FooBar extends PureComponent {
constructor(props) {
super(props);
+ this.dropdownOptions = [{
+ text: 'Scan',
+ icon: require('../images/scan.png'),
+ onPress: this.toScan,
+ }, {
+ text: 'Share',
+ icon: require('../images/share.png'),
+ onPress: this.toShare,
+ }];
+ adjustDropdownStyle = style => {
+ return {
+ width: 110,
+ height: 96, // calculated from margin and height of renderDropdownItem bellow
+ right: 0,
+ top: style.top,
+ };
+ }
+
+ renderDropdownItem = (item, index, highlighted) => {
+ return (
+ <View style={{alignItems: 'center', flexDirection: 'row'}}>
+ <Image source={item.icon} style={{margin: 10, width: 28, height: 28 }}/>
+ <Text style={{fontSize: 15}}>
+ {item.text}
+ </Text>
+ </View>
+ );
+ }
+
+ onDropdownSelect = (index, item) => item.onPress()
+
render() {
let navs = {
Center: {
text: 'Home',
},
Right: {
image: require('../images/more.png'),
+ onPress: () => this.dropdown && this.dropdown.show(),
},
};
<Header navs={navs}/>
+ <ModalDropdown
+ ref={view => {this.dropdown = view;}}
+ style={{height: 0}}
+ adjustFrame={this.adjustDropdownStyle}
+ options={this.dropdownOptions}
+ renderRow={this.renderDropdownItem.bind(this)}
+ onSelect={this.onDropdownSelect.bind(this)}
+ />
i use native-base
library to create menu, this is the documentation. you can try to search component you needed
https://docs.nativebase.io/Components.html#Components
this is one example i tried to make a menu
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import { Container, Content, Header, Body, Right, Button, Icon, Title, Drawer, Text } from 'native-base';
class SideBar extends Component {
render(){
return(
<Content style={{ backgroundColor: '#FFF' }} >
<Text>Account</Text>
<Text>SignOut</Text>
</Content>
)
}
}
export default class App extends Component {
closeDrawer = () => {
this.drawer._root.close()
}
openDrawer = () => {
this.drawer._root.open()
}
render(){
return(
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} />}
onClose={() => this.closeDrawer()} >
<Container>
<Header>
<Body>
<Title>Header</Title>
</Body>
<Right>
<Button transparent onPress={this.openDrawer} >
<Icon name='menu' />
</Button>
</Right>
</Header>
</Container>
</Drawer>
)
}
}
AppRegistry.registerComponent('Main', () => App);
you can style your own menu. maybe it can help you, thanks :)
I try to complete with your case, i add library react-native-drawer-layout
for create menu drawer layout . You can find in this for installation.
Step 1 - Create menu list (I created a separate to make it easier when I want to add another menu), It's content only ArrayList. I called that file Constants
, and you can write in Constants.js
like :
export const MENU_LIST = [
{ index: 1, name: 'Action' },
{ index: 2, name: 'Sign Out' },
]
Step 2 - I create Menu component for showing menu list. In Menu.js
you write like :
import React, { Component } from 'react';
import { View, ScrollView, Text, TouchableOpacity } from 'react-native';
const menuList = require('./Constants.js');
export default class Menu extends Component {
render() {
return (
<View style={{ flex:1, backgroundColor: '#33cc33'}}>
<ScrollView>
{menuList.MENU_LIST.map(item => (
<TouchableOpacity
key={item.index}
onPress={() => console.log('entered menu')}
>
<Text style={{color: 'white', fontSize: 16, paddingLeft: 20, paddingTop: 16}}>{item.name}</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
);
}
}
Step 3 - Refactor main component like :
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, View } from 'react-native';
import ActionBar from 'react-native-action-bar';
import DrawerLayout from 'react-native-drawer-layout';
import Menu from './Menu';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
drawerClosed: true,
};
this.toggleDrawer = this.toggleDrawer.bind(this);
this.setDrawerState = this.setDrawerState.bind(this);
}
setDrawerState() {
this.setState({
drawerClosed: !this.state.drawerClosed,
});
}
toggleDrawer = () => {
if (this.state.drawerClosed) {
this.DRAWER.openDrawer();
} else {
this.DRAWER.closeDrawer();
}
}
render() {
return (
<DrawerLayout
drawerWidth={300}
ref={drawerElement => {
this.DRAWER = drawerElement;
}}
drawerPosition={DrawerLayout.positions.left}
onDrawerOpen={this.setDrawerState}
onDrawerClose={this.setDrawerState}
renderNavigationView={() => <Menu />}
>
<ActionBar
containerStyle={styles.bar}
backgroundColor="#33cc33"
leftIconName={'menu'}
onLeftPress={this.toggleDrawer}/>
</DrawerLayout>
);
}
}
const styles = StyleSheet.create({
screen: {
backgroundColor: '#33cc33',
flex: 1,
paddingTop: 10,
alignItems: 'center',
//padding: 10
},
});
AppRegistry.registerComponent('Main', () => App);
In my emulator, that will display like:
and when i klik menu icon, that will display like:
UPDATE-1 :
if you want to make component drawer menu not fills up to bottom, you can play on style in component <Menu />
, i give margin for wrapper like:
const styles = StyleSheet.create({
wrapper: {
backgroundColor: '#33cc33',
marginTop: 50,
},
listMenu: {
color: 'white',
fontSize: 16,
paddingLeft: 20,
paddingTop: 12,
paddingBottom: 12,
}
});
And add style to component in <Menu />
like :
export default class Menu extends Component {
render() {
return (
<View style={styles.wrapper}> //add style wrapper
<ScrollView>
{menuList.MENU_LIST.map(item => (
<TouchableOpacity
key={item.index}
onPress={() => console.log('entered menu')}
>
<Text style={styles.listMenu}>{item.name}</Text> //add style menu
</TouchableOpacity>
))}
</ScrollView>
</View>
);
}
}
Full code in Menu.js
like :
import React, { Component, PropTypes } from 'react';
import { View, ScrollView, Text, TouchableOpacity, Image, StyleSheet } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
const menuList = require('./Constants.js');
export default class Menu extends Component {
render() {
return (
<View style={styles.wrapper}>
<ScrollView>
{menuList.MENU_LIST.map(item => (
<TouchableOpacity
key={item.index}
onPress={() => console.log('entered menu')}
>
<Text style={styles.listMenu}>{item.name}</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
wrapper: {
backgroundColor: '#33cc33',
marginTop: 50,
},
listMenu: {
color: 'white',
fontSize: 16,
paddingLeft: 20,
paddingTop: 12,
paddingBottom: 12,
}
});
And the result like :
UPDATE-2 :
based on your case in the comments, if you want to change position menu
to the right. You must change position the drawer first.
Actually :
main
file like : render() {
return (
<DrawerLayout
/* This for set width drawer */
drawerWidth={300}
/* end */
ref={drawerElement => {
this.DRAWER = drawerElement;
}}
/* This for set position drawer */
drawerPosition={DrawerLayout.positions.left}
/* end */
onDrawerOpen={this.setDrawerState}
onDrawerClose={this.setDrawerState}
renderNavigationView={() => <Menu />}
>
<ActionBar
containerStyle={styles.bar}
backgroundColor="#33cc33"
leftIconName={'menu'}
onLeftPress={this.toggleDrawer}
/>
</DrawerLayout>
);
}
Hopelly :
render() {
return (
<DrawerLayout
drawerWidth={300}
ref={drawerElement => {
this.DRAWER = drawerElement;
}}
// i change the position to the right.
drawerPosition={DrawerLayout.positions.Right}
onDrawerOpen={this.setDrawerState}
onDrawerClose={this.setDrawerState}
renderNavigationView={() => <Menu />}
>
<ActionBar
containerStyle={styles.bar}
backgroundColor="#33cc33"
rightIcons={[
{
name: 'menu',
onPress: this.toggleDrawer,
},
]}
/>
</DrawerLayout>
);
}
if you want to learn about DrawerLayout on Android you can read the documentation.
for the case, my emulator showing like :
I hope my answer can to help you and give your another idea to develop your apps. fighting... ;))