react-native - 导航器和toolbarAndroid

时间:2016-08-01 15:27:23

标签: react-native react-native-android

有没有办法在应用程序的每个屏幕上只使用一个toolbarAndroid与导航器一起使用。

我在index.android.js中设置了一个导航器:

import React, { Component } from 'react';

import {
  AppRegistry,
  Navigator,
} from 'react-native';

import ContactList from './src/containers/ContactList.js';

class MyIndex extends Component {
  render() {
    return (
      <Navigator
        initialRoute={{ name: 'index', component: ContactList }}
        renderScene={(route, navigator) => {
          if (route.component) {
            return React.createElement(route.component, { navigator, ...route.props });
          }

          return undefined;
        }}
      />
    );
  }
}

AppRegistry.registerComponent('reactest', () => MyIndex);

第一个屏幕显示联系人列表:

import React, { Component, PropTypes } from 'react';
import {
  Text,
  View,
  TouchableOpacity,
  TouchableHighlight,
  ListView,
  Image,
  ActivityIndicator,
  ToolbarAndroid,
} from 'react-native';

import styles from '../../styles';
import ContactDetails from './ContactDetails';
import logo from '../images/ic_launcher.png';

const url = 'http://api.randomuser.me/?results=15&seed=azer';

export default class ContactList extends Component {
  static propTypes = {
    navigator: PropTypes.object.isRequired,
  }
  constructor(props) {
    super(props);

    const datasource = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      animating: false,
      animatingSize: 0,
      jsonData: datasource.cloneWithRows([]),
      ds: datasource,
      appTitle: 'Test',
      appLogo: logo,
    };
  }
  _handlePress() {
    this.setState({
      animating: true,
      animatingSize: 80,
    });


    return fetch(url)
      // convert to json
      .then((response) => response.json())
      // do some string manipulation on json
      .then(({ results }) => {
        const newResults = results.map((user) => {
          const newUser = {
            ...user,
            name: {
              title: `${user.name.title.charAt(0).toUpperCase()}${user.name.title.slice(1)}`,
              first: `${user.name.first.charAt(0).toUpperCase()}${user.name.first.slice(1)}`,
              last: `${user.name.last.charAt(0).toUpperCase()}${user.name.last.slice(1)}`,
            },
          };

          return newUser;
        });

        return newResults;
      })
      // set state
      .then((results) => {
        this.setState({
          appSubTitle: 'Contacts list',
          animating: false,
          animatingSize: 0,
          jsonData: this.state.ds.cloneWithRows(results),
        });
      });
  }
  renderRow(rowData: string) {
    return (
      <TouchableHighlight
        onPress={() => {
          this.props.navigator.push({
            first: rowData.name.first,
            component: ContactDetails,
            props: {
              title: rowData.name.title,
              first: rowData.name.first,
              last: rowData.name.last,
              picture: rowData.picture.large,
              thumbnail: rowData.picture.thumbnail,
            },
          });
        }}
      >
        <View style={styles.listview_row}>
          <Image
            source={{ uri: rowData.picture.thumbnail }}
            style={{ height: 48, width: 48 }}
          />
          <Text>
            {rowData.name.title} {rowData.name.first} {rowData.name.last}
          </Text>
        </View>
      </TouchableHighlight>
    );
  }
  render() {
    const view = (
      <View style={styles.container}>
        <ToolbarAndroid
          logo={this.state.appLogo}
          title={this.state.appTitle}
          subtitle={this.state.appSubTitle}
          style={[{ backgroundColor: '#e9eaed', height: 56 }]}
        />
        <ActivityIndicator
          animating={this.state.animating}
          style={[styles.centering, { height: this.state.animatingSize }]}
        />
        <TouchableOpacity
          onPress={() => this._handlePress()}
          style={styles.button}
          size="large"
        >
          <Text>Fetch results?</Text>
        </TouchableOpacity>
        <ListView
          enableEmptySections
          dataSource={this.state.jsonData}
          renderRow={(rowData) => this.renderRow(rowData)}
          onPress={() => this._handleRowClick()}
        />
      </View>
    );

    return view;
  }
}

,第二个显示联系方式:

import React, {
  Component,
  PropTypes,
} from 'react';

import {
  Text,
  View,
  Image,
  ToolbarAndroid,
} from 'react-native';

import styles from '../../styles';

export default class ContactDetails extends Component {
  constructor(props) {
    super(props);

    this.state = {
      animating: false,
      animatingSize: 0,
      appTitle: 'Test',
      appLogo: { uri: this.props.thumbnail, height: 56 },
      appSubTitle: `Contact Details - ${this.props.first} ${this.props.last}`,
    };
  }
  render() {
    return (
      <View style={styles.container}>
        <ToolbarAndroid
          logo={this.state.appLogo}
          title={this.state.appTitle}
          subtitle={this.state.appSubTitle}
          style={[{ backgroundColor: '#e9eaed', height: 56 }]}
        />
        <Image
          source={{ uri: this.props.picture }}
          style={{ height: 128, width: 128 }}
        />
        <Text>{this.props.title} {this.props.first} {this.props.last}</Text>
      </View>
    );
  }
}

ContactDetails.propTypes = {
  title: PropTypes.string.isRequired,
  first: PropTypes.string.isRequired,
  last: PropTypes.string.isRequired,
  picture: PropTypes.string.isRequired,
  thumbnail: PropTypes.string.isRequired,
};

我在第一个屏幕上设置了too​​lbarAndroid,在我的第二个屏幕中设置了另一个,它运行良好,但我觉得最好只定义一个toolbarAndroid并更新它调用setState。

是否有可能,如果是这样的话?

2 个答案:

答案 0 :(得分:0)

用你的Navigator包裹你的ToolbarAndroid课程。这样,Navigator上呈现的所有内容都将被Toolbar包裹。实际上,这些场景之间的所有共同点都应该放在一个包含其余场景的组件上。

class MyIndex extends Component {
  render() {
    return (
      <ToolbarAndroid>
        <Navigator
          initialRoute={{ name: 'index', component: ContactList }}
          renderScene={(route, navigator) => {
            if (route.component) {
              return React.createElement(route.component, { navigator, ...route.props });
            }

            return undefined;
          }}
        />
      </ToolbarAndroid>
    );
  }
}

答案 1 :(得分:0)

我设法通过将toolbarAndroid和导航器包装在视图中来实现:

class MyIndex extends Component {
  constructor(props) {
    super(props);

    this.state = {
      appTitle: 'Test',
      appLogo: logo,
    };
  }
  render() {
    return (
      <View
        style={styles.container}
      >
        <ToolbarAndroid
          logo={this.state.appLogo}
          title={this.state.appTitle}
          subtitle={this.state.appSubTitle}
          style={[{ backgroundColor: '#e9eaed', height: 56 }]}
        />
        <Navigator
          initialRoute={{ name: 'index', component: ContactList }}
          renderScene={(route, navigator) => {
            if (route.component) {
              return React.createElement(route.component, { navigator, ...route.props });
            }

            return undefined;
          }}
        />
      </View>
    );
  }
}