react-native-side-menu

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

import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    Image,
    TouchableOpacity,
    ViewPagerAndroid,
    Navigator,
    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 {
    render() {
        let defaultName = 'WelcomeUI';
        let defaultComponent = WelcomeUI;
        return (
            <Navigator
                initialRoute={{name: defaultName, component: defaultComponent}}
                //配置场景
                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);
Button
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

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

export default class Button extends Component {

    //开始 前进 后退 最后 还加1个  总共5个按钮的通用写法

    constructor(props) {
        super(props);

    }


    _handlePress = () => {
        if (this.props.enabled && this.props.onPress) {
            //按钮可以按 没有变灰  则启用按钮的onPress()方法
            this.props.onPress();
        }
    }


    render() {
        //这个View有2个样式,第二个样式是用来覆盖的(加了背景颜色和透明度)
        return (
            <TouchableWithoutFeedback onPress={this._handlePress}>

                <View style={[styles.button, this.props.enabled ? {} : styles.buttonDisabled]}>
                    <Text style={styles.buttonText}>{this.props.text}</Text>
                </View>
            </TouchableWithoutFeedback>
        );
    }
}


const styles = StyleSheet.create({
    button: {
        flex: 1,
        width: 0,
        margin: 5,
        borderColor: 'gray',
        borderWidth: 1,
        backgroundColor: 'gray',
    },
    buttonDisabled: {
        backgroundColor: 'black',
        opacity: 0.5,
    },
    buttonText: {
        color: 'white',
    },
});


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',
    },


});

Menu
import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Dimensions,
    ScrollView,
    Text,
    Image,
    View,
} from 'react-native';

const window = Dimensions.get('window');
const uri = 'http://image18-c.poco.cn/mypoco/myphoto/20160605/09/1735166522016060509185507.png';

const styles = StyleSheet.create({
    menu: {
        flex: 1,
        width: window.width,
        height: window.height,
        backgroundColor: 'gray',
        padding: 20,
    },
    avatarContainer: {
        marginBottom: 20,
        marginTop: 20,
    },
    avatar: {
        width: 48,
        height: 48,
        borderRadius: 24,
        flex: 1,
    },
    name: {
        position: 'absolute',
        left: 70,
        top: 20,
    },
    item: {
        fontSize: 16,
        fontWeight: '300',
        paddingTop: 10,
    },
});

export default class Menu extends Component {

    static propTypes = {
        onItemSelected: React.PropTypes.func.isRequired,
    };// 注意这里有分号

    render() {
        return (
            <ScrollView scrollsToTop={false} style={styles.menu}>
                <View style={styles.avatarContainer}>
                    <Image
                        style={styles.avatar}
                        source={{uri: uri}}/>
                    <Text style={styles.name}>东方耀QQ昵称</Text>
                </View>

                <Text
                    onPress={() => this.props.onItemSelected('关于作者')}
                    style={styles.item}>
                    关于作者
                </Text>

                <Text
                    onPress={() => this.props.onItemSelected('联系东方耀')}
                    style={styles.item}>
                    联系东方耀
                </Text>
            </ScrollView>
        );
    }
};
HomeUI
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */

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

import SideMenu from 'react-native-side-menu';

import Menu from './Menu.js';//导入 菜单 组件

const uri_image_menu = 'http://image18-c.poco.cn/mypoco/myphoto/20160605/09/17351665220160605093956066.png';

export default class HomeUI extends Component {

    // state = {
    //     isOpen: false,
    //     selectedItem: 'About',
    // };

    constructor(props) {
        super(props);
        this.state = {
            isOpen: false,
            selectedItem: 'About',
        };
    }


    toggle() {
        this.setState({
            isOpen: !this.state.isOpen,
        });
    }

    updateMenuState(isOpen) {
        this.setState({isOpen: isOpen});
    }

    onMenuItemSelected = (item) => {
        this.setState({
            isOpen: false,
            selectedItem: item,
        });
    }


    render() {
        const menu = <Menu onItemSelected={this.onMenuItemSelected}/>;

        return (
            <SideMenu
                menu={menu}
                isOpen={this.state.isOpen}
                onChange={(isOpen) => this.updateMenuState(isOpen)}>
                <View style={styles.container}>
                    <Text style={styles.welcome}>
                        Welcome to React Native!
                    </Text>
                    <Text style={styles.instructions}>
                        To get started, edit index.android.js
                    </Text>
                    <Text style={styles.instructions}>
                        Press Cmd+R to reload, {'\n'}
                        Cmd+Control+Z for dev menu
                    </Text>
                    <Text style={[styles.instructions, {color: 'red'}]}>
                        当前选中的菜单是: {this.state.selectedItem}
                    </Text>
                </View>

                <Button style={styles.button} onPress={() => this.toggle()}>
                    <Image
                        source={{uri: uri_image_menu, width: 32, height: 32,}}/>
                </Button>

            </SideMenu>
        );
    }
}


class Button extends Component {
    handlePress(e) {
        if (this.props.onPress) {
            this.props.onPress(e);
        }
    }

    render() {
        return (
            <TouchableOpacity
                onPress={this.handlePress.bind(this)}
                style={this.props.style}>
                <Text>{this.props.children}</Text>
            </TouchableOpacity>
        );
    }
}


const styles = StyleSheet.create({

    button: {
        position: 'absolute',
        top: 20,
        padding: 10,
    },
    caption: {
        fontSize: 20,
        fontWeight: 'bold',
        alignItems: 'center',
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },


});



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值