RN组件通讯(一)

DfyProject01
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Image,
  TouchableOpacity,
  ViewPagerAndroid,
  Navigator,
  Platform,
  BackAndroid,
  ToastAndroid,
  View
} from 'react-native';

import LikeCount from './LikeCount.js';//导入喜欢数 组件
import Button from './Button.js';//导入 自定义的按钮的 组件
import HomeUI from './HomeUI.js';//导入 首页 组件

const PAGES = 5;

const BGCOLOR = ['#fdc08e', '#fff6b9', '#99d1b7', '#dde5fe', '#f79273'];

const IMAGE_URIS = [
  'http://apod.nasa.gov/apod/image/1410/20141008tleBaldridge001h990.jpg',
  'http://apod.nasa.gov/apod/image/1409/volcanicpillar_vetter_960.jpg',
  'http://apod.nasa.gov/apod/image/1409/m27_snyder_960.jpg',
  'http://apod.nasa.gov/apod/image/1409/PupAmulti_rot0.jpg',
  'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png',
];

class ProgressBar extends Component {
  //进度条组件
  constructor(props) {
    super(props);

  }
  render() {
    //当前位置+偏移量
    var fractionalPosition = (this.props.progress.position + this.props.progress.offset);

    var progressBarSize = (fractionalPosition / (PAGES - 1)) * this.props.size;
    return (
      //这进度条 2个view搞定了 通过宽度来区别
      //progressBarSize当前的进度
      //this.props.size总共的大小 或者 是进度的长度
      <View style={[styles.progressBarContainer, { width: this.props.size }]}>

        <View style={[styles.progressBar, { width: progressBarSize }]}/>

      </View>
    );
  }
}


class WelcomeUI extends Component {
  //引导页 或者 欢迎界面  用viewpager实现

  //null is not an object 解决办法:初始化的时候要用constructor 而不是getInitialState
  //current using ES6 as standart programming.

  //to initial state you must create cnostructor in your react component class

  //用构造函数来替代之前的 Initial实例化

  constructor(props) {
    super(props);
    this.state = {
      page: 0,
      animationsAreEnabled: true,//动画是否开启
      progress: {
        position: 0,
        offset: 0,
      },
    };

    //undefined is not a function (evaluating
    //React components using ES6 classes no longer autobind this to non React methods

    //this.setState=this.setState.bind(this);

  }


  //getInitialState(){
  //  return {
  //    page: 0,
  //    animationsAreEnabled: true,
  //    progress: {
  //      position: 0,
  //      offset: 0,
  //    },
  //  };
  //}


  onPageSelected = (e) => {
    //这个回调会在页面切换完成后(当用户在页面间滑动)调用
    //回调参数中的event.nativeEvent对象
    this.setState({ page: e.nativeEvent.position });
  }


  //onPageScroll(e){
  //  //当在页间切换时(不论是由于动画还是由于用户在页间滑动/拖拽)执行。
  //  this.setState({progress:e.nativeEvent});
  //}

  //See React on ES6+
  onPageScroll = (e) => {
    //当在页间切换时(不论是由于动画还是由于用户在页间滑动/拖拽)执行。

    //    回调参数中的event.nativeEvent对象会包含如下数据:
    //
    //position 从左数起第一个当前可见的页面的下标。
    //
    //offset 一个在[0,1)(大于等于0,小于1)之间的范围,代表当前页面切换的状态。值x表示现在"position"所表示的页有(1 - x)的部分可见,而下一页有x的部分可见。
    this.setState({ progress: e.nativeEvent });
  }


  move(delta) {
    var page = this.state.page + delta;
    this.go(page);
  }


  go(page) {
    if (this.state.animationsAreEnabled) {
      this.viewPager.setPage(page);
    } else {
      this.viewPager.setPageWithoutAnimation(page);
    }
    //刷新了
    this.setState({ page });
  }

  onClick = () => {
    //alert('点击了');
    const { navigator } = this.props;
    //为什么这里可以取得 props.navigator?请看上文:
    //<Component {...route.params} navigator={navigator} />
    //这里传递了navigator作为props
    if (navigator) {
      navigator.push({
        name: 'HomeUI',
        component: HomeUI,
      })
    }
  }

  render() {
    const thunbsUp = '\uD83D\uDC4D';
    var pages = [];
    for (var i = 0; i < PAGES; i++) {
      var pageStyle = {
        backgroundColor: BGCOLOR[i % BGCOLOR.length],
        alignItems: 'center',
        padding: 20,
      };
      if (i < PAGES - 1) {
        //前面几个viewpage

        //collapsable 如果一个View只用于布局它的子组件,
        // 则它可能会为了优化而从原生布局树中移除。 把此属性设为false可以禁用这个优化,以确保对应视图在原生结构中存在。
        pages.push(
          <View key={i} style={pageStyle} collapsable={false}>
            <Image
              style={styles.image}
              source={{ uri: IMAGE_URIS[i % BGCOLOR.length] }}
              />
            <LikeCount />
          </View>
        );
      } else {
        //最后一个viewpage 加了一个按钮
        pages.push(
          <View key={i} style={pageStyle} collapsable={false}>
            <Image
              style={styles.image}
              source={{ uri: IMAGE_URIS[i % BGCOLOR.length] }}
              />
            <LikeCount />


            <TouchableOpacity onPress={this.onClick} style={styles.startupButton}>
              <Text style={styles.likesText}>{thunbsUp + '启动首页'}</Text>

            </TouchableOpacity>
          </View>
        );
      }

    }

    var { page, animationsAreEnabled } = this.state;

    //var page=this.state.page;
    //var animationsAreEnabled=this.state.animationsAreEnabled;

    return (
      <View style={styles.container}>
        <ViewPagerAndroid
          style={styles.viewPager}
          initialPage={0}
          onPageScroll={this.onPageScroll}
          onPageSelected={this.onPageSelected}
          ref={viewPager => { this.viewPager = viewPager; } }>
          {pages}
        </ViewPagerAndroid>
        <View style={styles.buttons}>
          { animationsAreEnabled ?
            <Button
              text="Turn off animations"
              enabled={true}
              onPress={() => this.setState({ animationsAreEnabled: false }) }
              /> :
            <Button
              text="Turn animations back on"
              enabled={true}
              onPress={() => this.setState({ animationsAreEnabled: true }) }
              /> }
        </View>
        <View style={styles.buttons}>
          <Button text="Start" enabled={page > 0} onPress={() => this.go(0) }/>
          <Button text="Prev" enabled={page > 0} onPress={() => this.move(-1) }/>

          <Text style={styles.buttonText}>页:{page + 1} / {PAGES}</Text>
          <ProgressBar size={100} progress={this.state.progress}/>

          <Button text="Next" enabled={page < PAGES - 1} onPress={() => this.move(1) }/>
          <Button text="Last" enabled={page < PAGES - 1} onPress={() => this.go(PAGES - 1) }/>
        </View>
      </View>
    );
  }
}


class DfyProject01 extends Component {

  componentWillMount() {
    if (Platform.OS === 'android') {
      BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
      // BackAndroid.addEventListener('sss',this.onBackAndroid,true);
    }
  }
  componentWillUnmount() {
    if (Platform.OS === 'android') {
      BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
    }
  }

  onBackAndroid = () => {
    const navigator = this.refs.navigator;
    const routers = navigator.getCurrentRoutes();
    console.log('当前路由长度:' + routers.length);
    if (routers.length > 2) {
      navigator.pop();
      return true;//接管默认行为
    } else {

      //到了主页了
      if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
        //最近2秒内按过back键,可以退出应用。
        return false;
      }
      this.lastBackPressed = Date.now();
      ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
      return true;
    }
    // return false;//默认行为

  };



  render() {
    let defaultName = 'WelcomeUI';
    let defaultComponent = WelcomeUI;
    return (
      <Navigator
        initialRoute={{ name: defaultName, component: defaultComponent }}
        //配置场景
        ref="navigator"
        configureScene=
        {
          (route) => {

            //这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js

            return Navigator.SceneConfigs.FloatFromRight;
          }
        }
        renderScene={
          (route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator} />
          }
        } />
    );
  }
}

const styles = StyleSheet.create({
  buttons: {
    flexDirection: 'row',
    height: 30,
    backgroundColor: 'black',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  image: {
    width: 300,
    height: 200,
    padding: 20,
  },

  startupButton: {
    backgroundColor: 'rgba(0, 0, 0, 0.1)',
    borderColor: '#333333',
    borderWidth: 1,
    borderRadius: 5,
    margin: 8,
    padding: 8,
  },


  progressBarContainer: {
    height: 10,
    margin: 10,
    borderColor: '#eeeeee',
    borderWidth: 2,
  },
  progressBar: {
    alignSelf: 'flex-start',
    flex: 1,
    backgroundColor: '#ff0000',
  },
  viewPager: {
    flex: 1,
  },
  buttonText: {
    color: 'white',
  },
});


AppRegistry.registerComponent('DfyProject01', () => DfyProject01);
HomeUI
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    WebView,
    ScrollView,
    Image,
    AsyncStorage,
    TouchableOpacity,
    Platform,
    BackAndroid,
    View,
} from 'react-native';

import Dimensions from 'Dimensions';


const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;

const Model = [
    {
        id: '1',
        title: '猕猴桃1',
        desc: '12个装',
        price: 99,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '2',
        title: '牛油果2',
        desc: '6个装',
        price: 59,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '3',
        title: '猕猴桃3',
        desc: '3个装',
        price: 993,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '4',
        title: '猕猴桃4',
        desc: '4个装',
        price: 994,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '5',
        title: '猕猴桃5',
        desc: '5个装',
        price: 995,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '6',
        title: '猕猴桃6',
        desc: '6个装',
        price: 996,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },

];


export default class HomeUI extends Component {
    
    _pressButton() {
        const { navigator } = this.props;
        if (navigator) {
            //很熟悉吧,入栈出栈~ 把当前的页面pop掉,这里就返回到了上一个页面:了
            navigator.pop();
        }
    }
    
    render() {
        return (
            <List navigator={this.props.navigator} />
        );
    }
}


class Item extends Component {

    static defaultProps = {
        url: 'https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png',
        title: '默认标题',
    };  // 注意这里有分号
    static propTypes = {
        url: React.PropTypes.string.isRequired,
        title: React.PropTypes.string.isRequired,
    };  // 注意这里有分号
    
    render() {
        return (
            <View style={styles.item}>
                <TouchableOpacity onPress={this.props.press}>
                    <Image resizeMode='contain'
                        style={styles.img}
                        source={{ uri: this.props.url }}
                        >

                        <Text numberOfLines={1} style={styles.item_text}>{this.props.title}</Text>

                    </Image>
                </TouchableOpacity>
            </View>
        );
    }
}

class List extends Component {

    constructor(props) {
        super(props);

        this.state = {
            count: 0,
        };
    }

    shouldComponentUpdate() {
        console.log('List----shouldComponentUpdate');
        return true;
    }

    componentWillUpdate() {
        console.log('List----componentWillUpdate');
    }

    componentDidUpdate() {
        console.log('List----componentDidUpdate');
    }


    componentWillMount() {
        console.log('List---componentWillMount');
        let navigator = this.props.navigator;


        let callback = (event) => {
            console.log(
                'List : 事件类型',
                {
                    route: JSON.stringify(event.data.route),
                    target: event.target,
                    type: event.type,
                }
            );

            if ('HomeUI' === event.data.route.name && 'didfocus' === event.type) {
                let _that = this;

                AsyncStorage.getAllKeys(
                    function (err, keys) {
                        if (err) {
                            //TODO:存储取数据出错
                            //给用户提示错误信息
                            console.log(err);
                        } else {
                            console.log('读取成功了的个数:' + keys.toString());
                        }
                        _that.setState({

                            count: keys.length,
                        });
                    }
                );

            }
        };

        // Observe focus change events from this component.
        this._listeners = [
            navigator.navigationContext.addListener('willfocus', callback),
            navigator.navigationContext.addListener('didfocus', callback),
        ];
    }


    componentWillUnmount() {
        console.log('List---componentWillUnmount');
        this._listeners && this._listeners.forEach(listener => listener.remove());
    }

    render() {

        console.log('List----render');
        let list = [];
        for (let i in Model) {
            if (i % 2 === 0) {
                //两个等号 :不判断类型
                //三个等号:判断类型
                let row = (
                    <View style={styles.row} key={i}>
                        <Item title={Model[i].title}
                            url={Model[i].url}
                            press={this.press.bind(this, Model[i]) }

                            ></Item>


                        <Item title={Model[parseInt(i) + 1].title}
                            url={Model[parseInt(i) + 1].url}
                            press={this.press.bind(this, Model[parseInt(i) + 1]) }
                            ></Item>
                        
                    </View>
                );
                list.push(row);

            }

        }

        let count = this.state.count;
        let str = null;
        if (count) {
            str = ',共' + count + '件商品';
        }
        
        return (
            <ScrollView style={{ marginTop: 10 }}>
                {list}
                <Text onPress={this.goGouWu.bind(this) } style={styles.btn}>去结算{str}</Text>


            </ScrollView>
        );
    }


    goGouWu() {
        //alert('点击了去购物车');
        const { navigator } = this.props;
        //为什么这里可以取得 props.navigator?请看上文:
        //<Component {...route.params} navigator={navigator} />
        //这里传递了navigator作为props
        if (navigator) {
            navigator.push({
                name: 'GouWu',
                component: GouWu,
            })
        }
    }


    press(data) {
        this.setState({
            count: this.state.count + 1,
        });
        //AsyncStorage异步存储
        AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function (err) {
            if (err) {
                //TODO:存储出错
                alert(err);


            } else {
                //alert('保存成功');
            }
        });
    }


    //生成随机ID:GUID 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符
    //GUID生成的代码来自于Stoyan Stefanov

    genId() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }).toUpperCase();
    }
    
    componentDidMount() {
        let _that = this;

        AsyncStorage.getAllKeys(
            function (err, keys) {
                if (err) {
                    //TODO:存储取数据出错
                    //给用户提示错误信息
                    console.log(err);
                } else {
                    console.log('读取成功了的个数:' + keys.toString());
                }
                _that.setState({

                    count: keys.length,
                });
            }
        );
    }










}


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

        this.state = {
            price: 0,
            data: [],
        };
    }



    render() {

        //第二次render的时候 data不为空了
        let data = this.state.data;
        let price = this.state.price;
        let list = [];
        for (let i in data) {
            price += parseFloat(data[i].price);
            list.push(
                <View style={[styles.row, styles.list_item]} key={i}>

                    <Text style={styles.list_item_desc}>
                        {data[i].title}
                        {data[i].desc}
                    </Text>

                    <Text style={styles.list_item_price}>人民币: {data[i].price}</Text>
                </View>
            );
        }

        let str = null;
        if (price) {
            str = ',共' + price.toFixed(2) + '元';
        }



        return (
            <ScrollView style={{ marginTop: 10 }}>
                {list}

                <Text style={styles.btn}>支付{str}</Text>
                <Text style={styles.clear} onPress={this.clearStorage.bind(this) }>清空购物车</Text>

            </ScrollView>
        );


    }


    componentDidMount() {
        let _that = this;
        AsyncStorage.getAllKeys(
            function (err, keys) {
                if (err) {
                    //TODO 存储数据出错
                    //return ;
                }
                //keys是字符串数组
                AsyncStorage.multiGet(keys, function (err, result) {
                    //得到的结构是二维数组
                    //result[i][0]表示我们存储的键   result[i][1]表示我们存储的值
                    let arr = [];
                    for (let i in result) {
                        arr.push(JSON.parse(result[i][1]));
                    }

                    _that.setState(
                        {
                            data: arr,
                        }
                    );


                });
            }
        );
    }

    clearStorage() {
        let _that = this;
        AsyncStorage.clear(function (err) {
            if (!err) {
                _that.setState({
                    data: [],
                    price: 0,
                });

                alert('购物车已经清空');
            }
        });
    }


}


const styles = StyleSheet.create({


    list_item: {
        marginLeft: 5,
        marginRight: 5,
        padding: 5,
        borderWidth: 1,
        height: 30,
        borderRadius: 3,
        borderColor: '#ddd',
    },


    list_item_desc: {
        flex: 2,
        fontSize: 15,
    },

    list_item_price: {
        flex: 1,
        fontSize: 15,
        textAlign: 'right',
    },

    clear: {
        marginTop: 10,
        backgroundColor: '#FF7200',
        color: '#fff',
        borderWidth: 1,
        borderColor: '#ddd',
        marginLeft: 20,
        marginRight: 10,
        lineHeight: 24,
        height: 33,
        fontSize: 18,
        textAlign: 'center',
        textAlignVertical: 'center',
    },

    btn: {
        flex: 1,
        backgroundColor: '#FF7200',
        height: 33,
        textAlign: 'center',
        textAlignVertical: 'center',
        color: '#fff',
        marginLeft: 10,
        marginRight: 10,
        lineHeight: 24,
        marginTop: 40,
        fontSize: 18,


    },

    row: {
        flexDirection: 'row',
        marginBottom: 10,
    },
    img: {
        flex: 1,
        backgroundColor: 'transparent',
    },
    item_text: {
        backgroundColor: '#000',
        opacity: 0.7,
        color: '#fff',
        height: 25,
        lineHeight: 18,
        textAlign: 'center',
        marginTop: 74,
    },
    item: {
        flex: 1,
        marginLeft: 5,
        borderWidth: 1,
        borderColor: '#ddd',
        marginRight: 5,
        height: 100,
    },
    list: {
        justifyContent: 'flex-start',
        flexDirection: 'row',
        flexWrap: 'wrap'
    },
    container: {

        flex: 1,
    },
    listView: {
        paddingTop: 20,
        backgroundColor: '#F5FCFF',
    },
    thumbnail: {
        width: 80,
        height: 80,
        borderRadius: 16,


    },
    //让rightContainer在父容器中占据Image之外剩下的全部空间。

    container1: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    title: {
        fontSize: 14,
        marginBottom: 8,

    },
    year: {
        fontSize: 14,

    },



});

ProgressBar
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Image,
  TouchableOpacity,
  ViewPagerAndroid,
  Navigator,
  Platform,
  BackAndroid,
  ToastAndroid,
  View
} from 'react-native';

import LikeCount from './LikeCount.js';//导入喜欢数 组件
import Button from './Button.js';//导入 自定义的按钮的 组件
import HomeUI from './HomeUI.js';//导入 首页 组件

const PAGES = 5;

const BGCOLOR = ['#fdc08e', '#fff6b9', '#99d1b7', '#dde5fe', '#f79273'];

const IMAGE_URIS = [
  'http://apod.nasa.gov/apod/image/1410/20141008tleBaldridge001h990.jpg',
  'http://apod.nasa.gov/apod/image/1409/volcanicpillar_vetter_960.jpg',
  'http://apod.nasa.gov/apod/image/1409/m27_snyder_960.jpg',
  'http://apod.nasa.gov/apod/image/1409/PupAmulti_rot0.jpg',
  'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png',
];

class ProgressBar extends Component {
  //进度条组件
  constructor(props) {
    super(props);

  }
  render() {
    //当前位置+偏移量
    var fractionalPosition = (this.props.progress.position + this.props.progress.offset);

    var progressBarSize = (fractionalPosition / (PAGES - 1)) * this.props.size;
    return (
      //这进度条 2个view搞定了 通过宽度来区别
      //progressBarSize当前的进度
      //this.props.size总共的大小 或者 是进度的长度
      <View style={[styles.progressBarContainer, { width: this.props.size }]}>

        <View style={[styles.progressBar, { width: progressBarSize }]}/>

      </View>
    );
  }
}


class WelcomeUI extends Component {
  //引导页 或者 欢迎界面  用viewpager实现

  //null is not an object 解决办法:初始化的时候要用constructor 而不是getInitialState
  //current using ES6 as standart programming.

  //to initial state you must create cnostructor in your react component class

  //用构造函数来替代之前的 Initial实例化

  constructor(props) {
    super(props);
    this.state = {
      page: 0,
      animationsAreEnabled: true,//动画是否开启
      progress: {
        position: 0,
        offset: 0,
      },
    };

    //undefined is not a function (evaluating
    //React components using ES6 classes no longer autobind this to non React methods

    //this.setState=this.setState.bind(this);

  }


  //getInitialState(){
  //  return {
  //    page: 0,
  //    animationsAreEnabled: true,
  //    progress: {
  //      position: 0,
  //      offset: 0,
  //    },
  //  };
  //}


  onPageSelected = (e) => {
    //这个回调会在页面切换完成后(当用户在页面间滑动)调用
    //回调参数中的event.nativeEvent对象
    this.setState({ page: e.nativeEvent.position });
  }


  //onPageScroll(e){
  //  //当在页间切换时(不论是由于动画还是由于用户在页间滑动/拖拽)执行。
  //  this.setState({progress:e.nativeEvent});
  //}

  //See React on ES6+
  onPageScroll = (e) => {
    //当在页间切换时(不论是由于动画还是由于用户在页间滑动/拖拽)执行。

    //    回调参数中的event.nativeEvent对象会包含如下数据:
    //
    //position 从左数起第一个当前可见的页面的下标。
    //
    //offset 一个在[0,1)(大于等于0,小于1)之间的范围,代表当前页面切换的状态。值x表示现在"position"所表示的页有(1 - x)的部分可见,而下一页有x的部分可见。
    this.setState({ progress: e.nativeEvent });
  }


  move(delta) {
    var page = this.state.page + delta;
    this.go(page);
  }


  go(page) {
    if (this.state.animationsAreEnabled) {
      this.viewPager.setPage(page);
    } else {
      this.viewPager.setPageWithoutAnimation(page);
    }
    //刷新了
    this.setState({ page });
  }

  onClick = () => {
    //alert('点击了');
    const { navigator } = this.props;
    //为什么这里可以取得 props.navigator?请看上文:
    //<Component {...route.params} navigator={navigator} />
    //这里传递了navigator作为props
    if (navigator) {
      navigator.push({
        name: 'HomeUI',
        component: HomeUI,
      })
    }
  }

  render() {
    const thunbsUp = '\uD83D\uDC4D';
    var pages = [];
    for (var i = 0; i < PAGES; i++) {
      var pageStyle = {
        backgroundColor: BGCOLOR[i % BGCOLOR.length],
        alignItems: 'center',
        padding: 20,
      };
      if (i < PAGES - 1) {
        //前面几个viewpage

        //collapsable 如果一个View只用于布局它的子组件,
        // 则它可能会为了优化而从原生布局树中移除。 把此属性设为false可以禁用这个优化,以确保对应视图在原生结构中存在。
        pages.push(
          <View key={i} style={pageStyle} collapsable={false}>
            <Image
              style={styles.image}
              source={{ uri: IMAGE_URIS[i % BGCOLOR.length] }}
              />
            <LikeCount />
          </View>
        );
      } else {
        //最后一个viewpage 加了一个按钮
        pages.push(
          <View key={i} style={pageStyle} collapsable={false}>
            <Image
              style={styles.image}
              source={{ uri: IMAGE_URIS[i % BGCOLOR.length] }}
              />
            <LikeCount />


            <TouchableOpacity onPress={this.onClick} style={styles.startupButton}>
              <Text style={styles.likesText}>{thunbsUp + '启动首页'}</Text>

            </TouchableOpacity>
          </View>
        );
      }

    }

    var { page, animationsAreEnabled } = this.state;

    //var page=this.state.page;
    //var animationsAreEnabled=this.state.animationsAreEnabled;

    return (
      <View style={styles.container}>
        <ViewPagerAndroid
          style={styles.viewPager}
          initialPage={0}
          onPageScroll={this.onPageScroll}
          onPageSelected={this.onPageSelected}
          ref={viewPager => { this.viewPager = viewPager; } }>
          {pages}
        </ViewPagerAndroid>
        <View style={styles.buttons}>
          { animationsAreEnabled ?
            <Button
              text="Turn off animations"
              enabled={true}
              onPress={() => this.setState({ animationsAreEnabled: false }) }
              /> :
            <Button
              text="Turn animations back on"
              enabled={true}
              onPress={() => this.setState({ animationsAreEnabled: true }) }
              /> }
        </View>
        <View style={styles.buttons}>
          <Button text="Start" enabled={page > 0} onPress={() => this.go(0) }/>
          <Button text="Prev" enabled={page > 0} onPress={() => this.move(-1) }/>

          <Text style={styles.buttonText}>页:{page + 1} / {PAGES}</Text>
          <ProgressBar size={100} progress={this.state.progress}/>

          <Button text="Next" enabled={page < PAGES - 1} onPress={() => this.move(1) }/>
          <Button text="Last" enabled={page < PAGES - 1} onPress={() => this.go(PAGES - 1) }/>
        </View>
      </View>
    );
  }
}


class DfyProject01 extends Component {

  componentWillMount() {
    if (Platform.OS === 'android') {
      BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
      // BackAndroid.addEventListener('sss',this.onBackAndroid,true);
    }
  }
  componentWillUnmount() {
    if (Platform.OS === 'android') {
      BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
    }
  }

  onBackAndroid = () => {
    const navigator = this.refs.navigator;
    const routers = navigator.getCurrentRoutes();
    console.log('当前路由长度:' + routers.length);
    if (routers.length > 2) {
      navigator.pop();
      return true;//接管默认行为
    } else {

      //到了主页了
      if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
        //最近2秒内按过back键,可以退出应用。
        return false;
      }
      this.lastBackPressed = Date.now();
      ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
      return true;
    }
    // return false;//默认行为

  };



  render() {
    let defaultName = 'WelcomeUI';
    let defaultComponent = WelcomeUI;
    return (
      <Navigator
        initialRoute={{ name: defaultName, component: defaultComponent }}
        //配置场景
        ref="navigator"
        configureScene=
        {
          (route) => {

            //这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js

            return Navigator.SceneConfigs.FloatFromRight;
          }
        }
        renderScene={
          (route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator} />
          }
        } />
    );
  }
}

const styles = StyleSheet.create({
  buttons: {
    flexDirection: 'row',
    height: 30,
    backgroundColor: 'black',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  image: {
    width: 300,
    height: 200,
    padding: 20,
  },

  startupButton: {
    backgroundColor: 'rgba(0, 0, 0, 0.1)',
    borderColor: '#333333',
    borderWidth: 1,
    borderRadius: 5,
    margin: 8,
    padding: 8,
  },


  progressBarContainer: {
    height: 10,
    margin: 10,
    borderColor: '#eeeeee',
    borderWidth: 2,
  },
  progressBar: {
    alignSelf: 'flex-start',
    flex: 1,
    backgroundColor: '#ff0000',
  },
  viewPager: {
    flex: 1,
  },
  buttonText: {
    color: 'white',
  },
});


AppRegistry.registerComponent('DfyProject01', () => DfyProject01);
LikeCount
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    TouchableOpacity,
    View
    } from 'react-native';

export default class LikeCount extends Component{
  //喜欢数 组件

  constructor(props){
    super(props);

    this.state={
      likes:0,
    };
  }



  onClick=()=>{
    this.setState({likes:this.state.likes + 1});
  }


  render(){
    //这是一个点赞的小图标 一个代码就搞定了
    const thunbsUp='\uD83D\uDC4D';
    return (
        <View style={styles.likeContainer}>
          <TouchableOpacity onPress={this.onClick} style={styles.likeButton}>
            <Text style={styles.likesText}>{thunbsUp+'Like'}</Text>

          </TouchableOpacity>

          <Text style={styles.likesText}>{this.state.likes+'个喜欢数'}</Text>
        </View>
    );
  }
}


const styles = StyleSheet.create({
  likeButton: {
    backgroundColor: 'rgba(0, 0, 0, 0.1)',
    borderColor: '#333333',
    borderWidth: 1,
    borderRadius: 5,
    flex: 1,
    margin: 8,
    padding: 8,
  },
  
  likeContainer: {
    flexDirection: 'row',
  },
  likesText: {
    flex: 1,
    fontSize: 18,
    alignSelf: 'center',
  },
 
 
});

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值