我正在尝试使DrawerLayout与Google Playstore类似。
这是我设法做到的,图像是从平板电脑上拍摄的。
我想设置DrawerLayout的长度,该长度适合内容。 为了更好地理解,在这种情况下,它应该在红线的位置结束。
对于适合内容的长度,我的意思是它应该包含各种菜单并留一些空间。
在这种情况下的示例:
import * as React from 'react';
import { StyleSheet } from 'react-native';
import DrawerLayout from './DrawerLayout';
export default class App extends React.Component {
constructor() {
super();
}
render() {
return (
<DrawerLayout
percent={75}
selected="opt6"
type="menu"
imageBackground="https://c.wallhere.com/photos/aa/44/glare_colorful_bright_circles-679384.jpg!d"
account={[
{
name: 'Giovanni Zappulà',
email: 'giovanni.zappula.90@xxx.xxx',
image:
'https://cdn1.iconfinder.com/data/icons/avatar-2-2/512/Casual_Man_2-512.png',
},
{
name: 'James Kejan',
email: 'james.kejan.90@xxx.xxx',
image:
'https://cdn1.iconfinder.com/data/icons/avatar-2-2/512/Casual_Man_1-512.png',
},
{
name: 'Jesse Black',
email: 'jesse.black.90@xxx.xxx',
image:
'https://cdn1.iconfinder.com/data/icons/avatar-2-2/512/Casual_Man_3-512.png',
},
{
name: 'Arthur Snaw',
email: 'arthur.s.aw90@xxx.xxx',
image:
'https://cdn0.iconfinder.com/data/icons/user-interface-vol-3-12/66/68-512.png',
},
]}
menu={[
{
type: 'menu',
name: 'opt0',
title: 'Le mie app e i miei giochi',
icon: 'apps',
colorText: '#000',
colorTextFocus: '#4CAF50',
colorIcon: '#8c8a8a',
colorIconFocus: '#4CAF50',
},
{
type: 'menu',
name: 'opt1',
title: 'Le mie notifiche',
icon: 'add-alert',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{
type: 'menu',
name: 'opt2',
title: 'Abbonamenti',
icon: 'refresh',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{ type: 'divider' },
{
type: 'menu',
name: 'opt3',
title: 'Home page',
icon: 'home',
colorText: '#000',
colorTextFocus: '#4CAF50',
colorIcon: '#4CAF50',
colorIconFocus: '#4CAF50',
},
{
type: 'menu',
name: 'opt4',
title: 'Giochi',
icon: 'videogame-asset',
colorText: '#000',
colorTextFocus: '#4CAF50',
colorIcon: '#4CAF50',
colorIconFocus: '#4CAF50',
},
{
type: 'menu',
name: 'opt5',
title: 'Film',
icon: 'local-movies',
colorText: '#000',
colorTextFocus: '#f44336',
colorIcon: '#f44336',
colorIconFocus: '#f44336',
},
{
type: 'menu',
name: 'opt6',
title: 'Libri',
icon: 'book',
colorText: '#000',
colorTextFocus: '#2196F3',
colorIcon: '#2196F3',
colorIconFocus: '#2196F3',
},
{
type: 'menu',
name: 'opt7',
title: 'Musica',
icon: 'music-video',
colorText: '#000',
colorTextFocus: '#FF9800',
colorIcon: '#FF9800',
colorIconFocus: '#FF9800',
},
{
type: 'menu',
name: 'opt8',
title: 'Edicola',
icon: 'featured-play-list',
colorText: '#000',
colorTextFocus: '#9C27B0',
colorIcon: '#9C27B0',
colorIconFocus: '#9C27B0',
},
{ type: 'divider' },
{
type: 'menu',
name: 'opt9',
title: 'Account',
icon: 'person-pin',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{
type: 'menu',
name: 'opt10',
title: 'Utilizza codice',
icon: 'code',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{
type: 'menu',
name: 'opt11',
title: 'Lista desideri',
icon: 'check-circle',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{
type: 'menu',
name: 'opt12',
title: 'Play Protect',
icon: 'verified-user',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
{
type: 'menu',
name: 'opt13',
title: 'Impostazioni',
icon: 'settings',
colorText: '#000',
colorTextFocus: '#607D8B',
colorIcon: '#8c8a8a',
colorIconFocus: '#607D8B',
},
]}
/>
);
}
}
const styles = StyleSheet.create({});
DrawerLayout.js:
import * as React from 'react';
import {
Text,
ScrollView,
View,
StyleSheet,
DrawerLayoutAndroid,
Dimensions,
ImageBackground,
Image,
TouchableNativeFeedback,
Platform,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
var { width } = Dimensions.get('window');
const RippleColor = (...args) =>
Platform.Version >= 21 ? TouchableNativeFeedback.Ripple(...args) : null;
export default class DrawerLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
account: this.props.account,
firstAccount: [],
secondAccount: [],
width: Dimensions.get('window').width,
selected: this.props.selected,
type: this.props.type,
};
this.openDrawer = this.openDrawer.bind(this);
}
openDrawer() {
this.drawer.openDrawer();
}
componentWillMount() {
var account = this.state.account;
var firstAccount = Object.assign({}, account[0]);
this.setState({ firstAccount });
account = account.slice(1);
//console.log('A', account);
var secondAccount = Object.assign([], account);
this.setState({ secondAccount });
}
componentDidMount() {
this.openDrawer();
}
viewBackground(el) {
return {
backgroundColor: this.state.selected == el.name ? '#e8e8e8' : '#fff',
};
}
textColor(el) {
return {
color: this.state.selected == el.name ? el.colorTextFocus : el.colorText,
};
}
_selected = e => {
this.setState({ selected: e.name });
};
_change = () => {
var type = this.state.type == 'menu' ? 'account' : 'menu';
this.setState({ type });
};
colorIcon(el) {
return this.state.selected == el.name ? el.colorIconFocus : el.colorIcon;
}
_changeAccount = firstAccount => {
this.setState({ firstAccount });
var secondAccount = this.state.account.filter(
el => el.email !== firstAccount.email
);
this.setState({ secondAccount });
console.log(secondAccount);
};
render() {
var { imageBackground, account, percent, menu } = this.props;
var drawerWidth = (width * percent) / 100;
//console.log('f', this.state.firstAccount);
//console.log('s', this.state.secondAccount);
var firstAccount = this.state.firstAccount;
var secondAccount = this.state.secondAccount;
var number = secondAccount.length >= 2 ? 2 : secondAccount.length;
var list = (
<View
style={{
marginTop: 8,
}}>
{menu.map(e => {
if (e.type == 'divider')
return (
<View
style={{
borderBottomColor: '#ccc',
borderBottomWidth: 1,
marginTop: 8,
marginBottom: 8,
}}
/>
);
else
return (
<TouchableNativeFeedback
onPress={this._selected.bind(this, e)}
delayPressIn={0}
delayPressOut={0}
useForeground={true}
background={RippleColor('#fff')}>
<View
style={[
{
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 15,
},
this.viewBackground(e),
]}>
<Icon name={e.icon} size={25} color={this.colorIcon(e)} />
<Text
style={[
{
marginTop: 16,
marginLeft: 30,
marginBottom: 16,
fontSize: 13,
textAlign: 'left',
fontWeight: 'bold',
},
this.textColor(e),
]}>
{e.title}
</Text>
</View>
</TouchableNativeFeedback>
);
})}
</View>
);
var accountList = (
<View>
{secondAccount.map(user => {
return (
<TouchableNativeFeedback
onPress={this._changeAccount.bind(this, user)}
delayPressIn={0}
delayPressOut={0}
useForeground={true}
background={RippleColor('#ccc')}>
<Text
style={{
marginTop: 16,
marginLeft: 30,
marginBottom: 16,
fontSize: 13,
textAlign: 'left',
fontWeight: 'bold',
}}>
{user.email}
</Text>
</TouchableNativeFeedback>
);
})}
</View>
);
var navigationView = (
<ScrollView style={{ flex: 1, backgroundColor: '#fff' }}>
<ImageBackground
source={{
uri: imageBackground,
}}
style={{ width: null, height: null, paddingBottom: 10 }}>
<View
style={{
flexDirection: 'row',
marginTop: 30,
marginLeft: 10,
marginRight: 10,
alignItems: 'center',
//backgroundColor: '#ccc'
}}>
<Image
source={{
uri: firstAccount.image,
}}
style={{ width: 60, height: 60 }}
/>
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
//backgroundColor: '#fff',
}}>
{secondAccount.slice(0, number).map(user => {
return (
<TouchableNativeFeedback
onPress={this._changeAccount.bind(this, user)}
delayPressIn={0}
delayPressOut={0}
useForeground={true}
background={RippleColor('#ccc')}>
<Image
source={{
uri: user.image,
}}
style={{ width: 40, height: 40, marginLeft: 15 }}
/>
</TouchableNativeFeedback>
);
})}
</View>
</View>
<TouchableNativeFeedback
onPress={this._change.bind(this)}
delayPressIn={0}
delayPressOut={0}
useForeground={true}
background={RippleColor('#ccc')}>
<View style={{ marginTop: 10 }}>
<Text
style={{
marginTop: 20,
marginLeft: 10,
fontSize: 15,
textAlign: 'left',
color: '#fff',
}}>
{firstAccount.name}
</Text>
<Text
style={{
marginLeft: 10,
fontSize: 15,
textAlign: 'left',
color: '#fff',
}}>
{firstAccount.email}
</Text>
</View>
</TouchableNativeFeedback>
</ImageBackground>
{this.state.type == 'menu' ? list : accountList}
</ScrollView>
);
return (
<DrawerLayoutAndroid
drawerWidth={drawerWidth}
ref={_drawer => (this.drawer = _drawer)}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{ flex: 1, alignItems: 'center' }}>
<Text style={{ margin: 50 }}>Hello World!</Text>
</View>
</DrawerLayoutAndroid>
);
}
}
const styles = StyleSheet.create({});
寻找博览会here。