zoukankan      html  css  js  c++  java
  • 【水滴石穿】douban-movies-react-native

    这个项目的话,倒是可以做一个支架页面,就是你需要什么东西,你就可以在里面加,不过也是比较难的地方
    就是数据流,数据处理的部分。react可以处理数据的方式很多,没有见过类似于古老的vue时候可以使用的
    $.http(),我觉得实现功能是第一步,至于技术的高低,哎,捂脸
    【博客后文把前面说的都否认了,talk is cheap,show me the code 】
    项目地址为:https://github.com/XinmengSiRan/douban-movies-react-native
    先看页面


    //index.js
    /** @format */
    
    import {AppRegistry} from 'react-native';
    import App from './App';
    import {name as appName} from './app.json';
    
    AppRegistry.registerComponent(appName, () => App);
    
    //App.js
    //定义了根App.js
    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     *
     * @format
     * @flow
     */
    
    import React, {Component} from 'react';
    import {StyleSheet, Text, View} from 'react-native';
    
    import AppContainer from './src';
    
    type Props = {
      navigation: any
    }; 
    export default class App extends Component <Props>{
      render() {
        return (
            <AppContainer />
        );
      }
    }
    
    //src/index.js
    //定义底部和切换页面
    import React, { Component } from 'react';
    import { Dimensions, AppRegistry, StyleSheet, Text, View, ButtonTouchableOpacity, Image, ScrollView, FlatList, ActivityIndicator} from 'react-native';
    import { createAppContainer, createStackNavigator, createBottomTabNavigator } from 'react-navigation';
    import { createStore} from 'redux';
    import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from 'react-native-scrollable-tab-view';
    
    import PlayList from './components/PlayList';
    import Search from './components/Search';
    import My from './components/My';
    import Icon from 'react-native-vector-icons/Ionicons';
    
    
    /*为了注释调试提醒*/
    console.ignoredYellowBox = ['Remote debugger'];
    const BottomTabNavigator = createBottomTabNavigator({
        热映: {
            //通过createStackNavigator中的值来切换页面
            screen: createStackNavigator({PlayList}),
            navigationOptions: {
                tabBarLabel: '热映',
                tabBarIcon: ({tintColor}) => (
                    <Icon name="ios-tv" size={20} color={tintColor} />
                )
            }
        },
        找片: {
            screen: createStackNavigator({Search}),
            navigationOptions: {
                tabBarLabel: '找片',
                tabBarIcon: ({tintColor}) => (
                    <Icon name="ios-eye" size={20} color={tintColor} />
                )
            }
        },
        我的: {
            screen: createStackNavigator({My}),
            navigationOptions: {
                tabBarLabel: '我的',
                tabBarIcon: ({tintColor}) => (
                    <Icon name="ios-person" size={20} color={tintColor} />
                )
            }
        }
    }, {
        tabBarPosition: 'bottom',
        tabBarOptions: {
            activeTintColor: '#494949',
            inactiveTintColor: '#999999',
            labelStyle: {
                fontSize: 12,
                marginBottom: 5
            },
            style: {
                borderTopWidth: 1,
                borderTopColor: '#eeeeee',
                height: 50,
                backgroundColor: '#ffffff'
            }
        }
    });
    //切换的底部页面
    const AppContainer = createAppContainer(BottomTabNavigator);
    
    export default AppContainer;
    //其实我比较好奇这种写法,一下子组件都引进来了,会不会首页太大很卡的问题
    

    //src/components/PlayList.js
    import React, { Component } from 'react';
    import { StyleSheet, Dimensions, Text, View, Button, FlatList } from 'react-native';
    import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
    import { createAppContainer, createStackNavigator} from 'react-navigation';

    import HotList from './HotList';
    import SoonList from './SoonList';

    export default class PlayList extends Component {
    //这里定义的头部
    static navigationOptions = {
    title: 'Home'
    };

    render() {
        return (
            <View style={styles.container}>
                <ScrollableTabView
                    renderTabBar={() => <DefaultTabBar/> }
                    tabBarUnderlineStyle={{
                        backgroundColor: '#000',
                        height: 2
                    }}
                    tabBarBackgroundColor='#fff'
                    tabBarActiveTextColor='#000'
                    tabBarInactiveTextColor='#959595'
                    tabBarTextStyle={{ fontSize: 16 }}
                    locked={false}
                >
                    <View tabLabel='正在热映' style={{marginBottom:50}}>
                        <HotList navigation={this.props.navigation}></HotList>
                    </View>
                    <View tabLabel='即将上映' style={{marginBottom:50}}>
                        <SoonList navigation={this.props.navigation}></SoonList>
                    </View>
    
                </ScrollableTabView>
            </View>
        );
    }
    

    }
    //在页面里面判断的是不是iphonex做不做别的适配
    const { width, height } = Dimensions.get('window');
    const IS_IPHONE_X_SERIES = () => {
    if (height == 812 || height == 896) {
    return true;
    }else{
    return false;
    }
    }

    const styles = StyleSheet.create({
    container: {
    width,
    height: IS_IPHONE_X_SERIES ? (height - 88 - 34) : (height - 64),
    paddingTop: 10,
    backgroundColor: '#fff'
    }
    });
    //里面有两个组件,代表的两个页面

    我一开始以为页面真的就是架子,可是分析代码发现里面是有数据请求的
    很惊讶阿,这种bug我不会调,先放代码
    ```js
    //src/components/HotList.js
    import React, { Component } from 'react';
    import { 
        ActivityIndicator,
        StyleSheet, 
        Dimensions,
        Image,
        Text,
        TouchableOpacity, 
        TouchableWithoutFeedback,
        View, 
        Button, 
        FlatList 
    } from 'react-native';
    
    import Star from './Star';
    
    export default class HotList extends Component {
        constructor(props) {
            super(props);
            this.state = {
                ready: true,
                refreshing: false,
                data: []
            }
        }
    
        componentDidMount() {
            this._fetchData();
        }
    
        handleOnPress = () => {
    
        }
        
        _fetchData = () => {
            fetch('https://api.douban.com/v2/movie/in_theaters')
            .then((response) => {
                this.setState({refreshing: false});
                return response.json();
            }).then((responseJson) => {
                console.log('response', responseJson);
                const dataArr = responseJson.subjects;
                this.setState({
                    ready: false,
                    refreshing: false,
                    data: dataArr
                });
    
            }).catch((error) => {
                console.error(error);
            });
        }
    
        _refreshData = () => {
            this.setState({refreshing: true});
            this._fetchData();
        }
        render() {
            const {navigate} = this.props.navigation;
            const {data} = this.state;
            return (
                <View style={styles.container}>
                {
                    this.state.ready 
                    ? <ActivityIndicator size='large' style={styles.loadding}/>
                    : <FlatList
                    data={data}
                    onRefresh={this._refreshData}
                    refreshing={this.state.refreshing}
                    keyExtractor={(item, index ) => index+item}
                    renderItem={({item}) => {
                        return (
                            <TouchableOpacity
                            style={styles.item}
                            onPress={this.handleOnPress}>
                                <View style={{flex: 1,}}>
                                    <Image 
                                    source={{uri: item.images.large}}
                                    style={styles.image} />
                                </View>
                                <View style={{flex: 2, alignItems: 'flex-start', paddingLeft: 5}}>
                                    <Text style={styles.title}>{item.title}</Text>
                                    <View style={styles.star}>
                                        <Star value={item.rating}></Star>
                                    </View>
                                    <Text style={styles.smallFont}>导演:{item.directors[0].name}</Text>
                                    <Text style={styles.smallFont}>主演:{item.casts.map((v)  => v.name).join('/')}</Text>
                                </View>
                                <View style={{alignItems: 'flex-end'}}>
                                    <Text style={[styles.smallFont, styles.redFont]}>{
                                        (item.collect_count / 10000.0 > 1) 
                                        ? (item.collect_count / 10000.0).toFixed(1) + '万人看过'
                                        : item.collect_count + '人看过'
    
                                    }
                                    </Text>
                                    <TouchableOpacity
                                    style={styles.buyTicket}>
                                        <Text style={styles.redFont}>购票</Text>
                                    </TouchableOpacity>
                                </View>
                            </TouchableOpacity>
                        );
                    }} />
                }  
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        loadding: {
            marginTop: 30
        },
        item: {
            height: 140,
            paddingLeft: 18,
            paddingRight: 18,
            paddingTop: 10,
            paddingBottom: 10,
            flexDirection: 'row',
            alignItems: 'center',
            borderBottomWidth: 1,
            borderBottomColor: '#eeeeee',
           
        },
        image: {
             80,
            height: 120,
        },
        title: {
            fontSize: 16,
            fontWeight: 'bold'
        },
        smallFont: {
            fontSize: 12,
            lineHeight: 20,
            color: '#A6A6A6'
        },
        buyTicket: {
             60,
            height: 30,
            marginTop: 5,
            borderRadius: 5,
            borderWidth: 1,
            borderColor:'#FF4E65',
            justifyContent: 'center',
            alignItems: 'center'
        },
        redFont: {
            color: '#FF4E65',
        },
        star: {
            marginTop: 10,
            marginBottom: 10
        }
    });
    
    //src/components/SoonList.js
    import React, { Component } from 'react';
    import { 
        ActivityIndicator,
        StyleSheet, 
        Image,
        Text,
        TouchableOpacity, 
        View, 
        FlatList,
    } from 'react-native';
    
    import Star from './Star';
    
    export default class SoonList extends Component {
        constructor(props) {
            super(props);
            this.state = {
                ready: true,
                refreshing: false,
                data: []
            }
        }
    
        componentDidMount() {
            this._fetchData();
        }
    
        handleOnPress = () => {
    
        }
    
        _fetchData = () => {
            fetch('https://api.douban.com/v2/movie/coming_soon')
            .then((response => {
                this.setState({refreshing: false});
                return response.json();
            })).then((responseJson) => {
                console.log(responseJson);
                const dataArr = responseJson.subjects;
                this.setState({
                    ready: false,
                    refreshing: false,
                    data: dataArr
                });
            }).catch((eror) => {
                console.error(error);
            });
        }
    
        _refreshData = () => {
            this.setState({refreshing: true});
            this._fetchData();
        }
    
        renderMovieItem = (item) => {
            return (
                <TouchableOpacity
                style={styles.item}
                onPress={this.handleOnPress}>
                    <View style={{flex: 1,}}>
                        <Image 
                        source={{uri: item.images.large}}
                        style={styles.image} />
                    </View>
                    <View style={{flex: 2, alignItems: 'flex-start', paddingLeft: 5}}>
                        <Text style={styles.title}>{item.title}</Text>
                        <View style={styles.star}>
                            <Star value={item.rating}></Star>
                        </View>
                        <Text style={styles.smallFont}>导演:{item.directors[0].name}</Text>
                        <Text style={styles.smallFont}>主演:{item.casts.map((v)  => v.name).join('/')}</Text>
                    </View>
                    <View style={{alignItems: 'flex-end'}}>
                        <Text style={[styles.smallFont, styles.yellowFont]}>{
                            (item.collect_count / 10000.0 > 1) 
                            ? (item.collect_count / 10000.0).toFixed(1) + '万人想看'
                            : item.collect_count + '人想看'
    
                        }
                        </Text>
                        <TouchableOpacity
                        style={styles.buyTicket}>
                            <Text style={styles.yellowFont}>想看</Text>
                        </TouchableOpacity>
                    </View>
                </TouchableOpacity>
            );
        }
    
        render() {
            const {data} = this.state;
            const {navigate} = this.props.navigation;
            return (
                <View>
                {
                    this.state.ready
                    ? <ActivityIndicator size='large' style={styles.loadding} />
                    : <FlatList
                    data={data}
                    onRefresh={this._refreshData}
                    refreshing={this.state.refreshing}
                    keyExtractor={(item, index) => index + item}
                    renderItem={({item}) => this.renderMovieItem(item)} />
                }
                </View>
            );
        }
        
    }
    
    const styles = StyleSheet.create({
        loadding: {
            marginTop: 30
        },
        item: {
            height: 140,
            paddingLeft: 18,
            paddingRight: 18,
            paddingTop: 10,
            paddingBottom: 10,
            flexDirection: 'row',
            alignItems: 'center',
            borderBottomWidth: 1,
            borderBottomColor: '#eeeeee',
           
        },
        image: {
             80,
            height: 120,
        },
        title: {
            fontSize: 16,
            fontWeight: 'bold'
        },
        smallFont: {
            fontSize: 12,
            lineHeight: 20,
            color: '#A6A6A6'
        },
        buyTicket: {
             60,
            height: 30,
            marginTop: 5,
            borderRadius: 5,
            borderWidth: 1,
            borderColor:'#EFA300',
            justifyContent: 'center',
            alignItems: 'center'
        },
        yellowFont: {
            color: '#EFA300'
        },
        star: {
            marginTop: 10,
            marginBottom: 10
        }
    });
    

    //src/components/Search.js
    import React, { Component } from 'react';
    import { Dimensions, Text, View, Button, FlatList } from 'react-native';
    import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
    import { createAppContainer, createStackNavigator} from 'react-navigation';
    
    const { width, height } = Dimensions.get('window');
    
    export default class Search extends Component {
        static navigationOptions = {
            title: 'Search',
        };
    
        render() {
            const { navigate } = this.props.navigation;
            return (
                <View>
                    <Text>找片</Text>
                </View>
            );
        }
    }
    

    //src/components/My.js
    import React, { Component } from 'react';
    import { Dimensions, Text, View, Button, FlatList } from 'react-native';
    import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
    import { createAppContainer, createStackNavigator} from 'react-navigation';
    
    const { width, height } = Dimensions.get('window');
    
    export default class My extends Component {
        static navigationOptions = {
            title: 'My'
        };
    
        render() {
            const { navigate } = this.props.navigation;
            return (
                <View>
                    <Text>我的</Text>
                </View>
            );
        }
    }
    

    时时当勉励,岁月不待人,加油~~~加油~~~

  • 相关阅读:
    layui + mvc + ajax 导出Excel功能
    PL/SQL Developer工具包和InstantClient连接Oracle 11g数据库
    .NET中JSON的序列化和反序列化的几种方式
    C# 编程中的堆栈(Stack)和队列(Queue)
    Oracle 数据库常用操作语句大全
    C#方法中参数ref和out的解析
    JS实现限行
    ajax+ashx 完美实现input file上传文件
    HTML5 学习
    Linux文件和目录操作管理命令
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10901007.html
Copyright © 2011-2022 走看看