反应适合内容的本机DrawerLayoutAndroid抽屉宽度

时间:2018-08-25 17:30:22

标签: javascript android react-native

我正在尝试使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

0 个答案:

没有答案