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

    先推荐一个学习的地址:https://ke.qq.com/webcourse/index.html#cid=203313&term_id=100240778&taid=1277855849978417&vid=s14139cbg2q
    我看了一下,挺全的,我接下来应该会根据这个视频自己做一个App?
    这个链接也是我在GitHub上面学习各位可爱的程序员的开源项目的时候看到的,接下来我们先来看这个博主的项目吧~
    先放github地址:https://github.com/linchengzzz/rnTest
    接下来我们来分析项目
    项目运行出来的效果,应该是接口有些问题



    接下来我们简单看看代码,发现亮点

    //index.js
    //这个是根入口文件
    /**
     * @format
     * @lint-ignore-every XPLATJSCOPYRIGHT1
     */
    
    import {AppRegistry} from 'react-native';
    // import App from './App';
    import App from './views/main.js';
    import {name as appName} from './app.json';
    
    AppRegistry.registerComponent(appName, () => App);
    

    我们接下来看main.js

    //views/main.js
    import React, { Component } from 'react';
    import { Icon } from 'react-native-elements';
    //引入页面
    import AboutPage from './book/about';
    import BookPage from './book/index';
    import MoviePage from './movie/index';
    import BookDetailsPage from './book/detail';
    import MovieDetailsPage from './common/webpage';
    import { createStackNavigator, createBottomTabNavigator, createAppContainer } from "react-navigation";
    //定义切换页面
    const bottomTabNavigator = createBottomTabNavigator({
            Book: BookPage,
            Movie: MoviePage,
            About: AboutPage
        }, {
            defaultNavigationOptions: ({ navigation }) => ({
                tabBarIcon: ({ focused, tintColor }) => {
                    const { routeName } = navigation.state;
                    let iconName;
                    if (routeName === 'Book') {
                        iconName = focused ? 'book' : 'book' ; //可以根据focused更换图标
                    } else if (routeName === 'Movie') {
                        iconName = 'movie';
                    }else{
                        iconName = 'stars';
                    }
                    return <Icon name={iconName} size={25} color={tintColor} />;
                },
            }),
            //定义激活颜色,有的是直接改变图片
            tabBarOptions: {
                //根据是否激活,改变颜色
                activeTintColor: 'tomato', 
                inactiveTintColor: 'gray',
            }
        });
        // 定义对应页面
    const AppStack = createStackNavigator(
        {
            bottomTabNavigator: {
                screen: bottomTabNavigator
            },
            Details: {
                screen: BookDetailsPage,
                // navigationOptions: {
                //     title: "图书详情"
                // }
            },
            MovieDetails:{
                screen: MovieDetailsPage,
            }
        }, {
            initialRouteName: "bottomTabNavigator",
            // 默认header bar样式配置
            defaultNavigationOptions: {
                headerTintColor: '#fff',
                headerStyle: {
                    backgroundColor: '#2596f3',
                    height: 0 //影藏header
                }
            },
        });
    const AppContainer = createAppContainer(AppStack);
    
    export default class App extends Component {
        render() {
            return (
                <AppContainer />
            );
        }
    }
    

    分析对应页面

    //views/book/about.js
    import React, { Component } from 'react';
    import { Text, View, ScrollView, StyleSheet } from 'react-native';
    export default class About extends Component {
        render(){
            return (
                <ScrollView>
                    <View style={styles.container}>
                        <Text style={styles.title}>
                            App Info
                        </Text>
                        <View style={styles.box}>
                            <Text style={styles.leftTitle}>版本</Text>
                            <Text style={styles.rightContent}>
                                v1.1_20190312
                            </Text>
                        </View>
                        <View style={styles.box}>
                            <Text style={styles.leftTitle}>课程地址</Text>
                            <Text style={styles.rightContent}>
                                https://ke.qq.com/webcourse/index.html#cid=203313&term_id=100240778&taid=1278010468801073&vid=e1414ek8gbc
                            </Text>
                        </View>
                        <View style={styles.box}>
                            <Text style={styles.leftTitle}>依赖组件</Text>
                            <Text style={styles.rightContent}>
                                react-native-elements、react-navigation、react-native-webview
                            </Text>
                        </View>
                        <View style={styles.box}>
                            <Text style={styles.leftTitle}>欠缺功能</Text>
                            <Text style={styles.rightContent}>
                                header:目前影藏了,设置了header高度为0
                            </Text>
                        </View>             
                    </View>
                </ScrollView>
            )
        }
    }
    var styles = StyleSheet.create({
        container: {
            flex: 1,
            padding: 10,
            marginTop: 0,
            lineHeight:30
        },
        title: {
            fontWeight: "bold",
            color: "#f33",
            fontSize: 20
        },
        box:{
            marginTop:20,
            flex:1
        },
        leftTitle:{
            fontSize:18,
            color:"#333",
            fontWeight:"800",
        },
        rightContent:{
            fontSize:16,
            color:"#999"
        }
    })
    
    //封装的searchBar
    //views/common/searchbar.js
    import React, { Component } from 'react';
    import { Text, View,TextInput, StyleSheet, TouchableOpacity } from 'react-native';
    
    export default class SearchBar extends Component {
    
        render() {
            return (
                <View style={styles.container}>
                    <View style={styles.inputContainer}>
                        <TextInput style={styles.input} {...this.props} />
                    </View>
                    <TouchableOpacity style={styles.btn} {...this.props}>
                        <Text style={styles.search}>搜索</Text>
                    </TouchableOpacity>
                </View>
            );
        }
    }
    
    var styles = StyleSheet.create({
        container:{
            flexDirection:"row",
            justifyContent:"flex-end",
            alignItems:"center",
            height:44,
            marginTop:10
        },
        inputContainer:{
            flex:1,
            marginLeft:5
        },
        input:{
            flex:1,
            height:44,
            borderWidth:1,
            borderRadius:4,
            borderColor:"#ccc",
            paddingLeft:5
        },
        btn:{
            55,
            height:44,
            marginLeft:5,
            marginRight:5,
            backgroundColor:"#23beff",
            borderRadius:4,
            justifyContent:"center",
            alignItems:"center"
        },
        search:{
            flex:1,
            color:"#fff",
            fontSize:15,
            fontWeight:"bold",
            textAlign:"center",
            lineHeight:44
        }
    })
    
    //views/book/index.js
    import React, { Component } from 'react';
    import { Text, View, ScrollView, Image, StyleSheet,TouchableOpacity } from 'react-native';
    import SearchBar from '../common/searchbar';
    import Util from '../common/util';
    import Api from '../common/api';
    export default class index extends Component {
        constructor(props) {
            super(props);
            this.state = {
                data: [],
                show: true,
                keyword: 'react'
            };
        }
        componentDidMount(){
            // 初次请求数据
            this.getData();
        }
        updateSearch = search => {
            this.setState({ keyword: search });   
        }
        //获取数据
        searchText=()=>{
            this.getData();
        }
        // 以下写法报错,不识别this
        // searchText (){
        //     this.getData();
        // }
        // Util.loading 工具函数定义的loading
        getData(){
            // 显示loading
            this.setState({
                show: false
            });
            // 请求数据
            var that = this;
            var url = Api.book_search + '?count=20&q=' + this.state.keyword;
            Util.getRequest(url, function (response) {
                // 请求成功
                if (!response.books || response.books.length == 0) {
                    return alert("未查询到数据");
                }
                // 显示loading,将请求结果赋值给data
                that.setState({
                    show: true,
                    data: response.books
                });
            }, function (error) {
                // 请求失败
                alert(error);
            });
        }
        render() {
            return (
                <ScrollView>
                    {/* 封装的搜索头部 */}
                    <SearchBar
                        placeholder="请输入关键词(书名、作者)..."
                        onChangeText={this.updateSearch}
                        onPress={this.searchText}
                    />
                    {
                        // 请求数据时显示loading,请求成功显示列表
                        this.state.show ?
                            <View style={styles.container} >
                                {
                                    this.state.data.map((item, i) => {
                                        return (
                                            <TouchableOpacity style={styles.list} key={i} onPress={() => this.props.navigation.push('Details', { 'bookID': item.id })}
                                                activeOpacity={0.5}>
                                                <Image source={{ uri: item.images.small }} style={styles.images} />
                                                <View style={styles.rightbox}>
                                                    <Text style={styles.title}>{item.title}</Text>
                                                    <Text>价格:{item.price ? item.price : '暂无'}</Text>
                                                    <Text>作者:{
                                                        item.author.map(
                                                            function(vo){
                                                                return vo + ' ';
                                                            }
                                                            )
                                                        }</Text>
                                                    <Text>{item.publisher} {item.pubdate}</Text>
                                                    <Text>{item.pages ? item.pages : '未知'} 页</Text>
                                                </View>
                                            </TouchableOpacity>
                                        );
                                    })
                                }
                            </View>                    
                        : Util.loading
                    }
                </ScrollView>
            )
        }   
    }
    
    var styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
            justifyContent: "center",
            padding:10,
            marginTop: 0
        },
        btn:{
            100,
            height:30
        },
        images: {  80, height: 100 },
        title:{
            fontWeight:"bold",
            color:"#f33"
        },
        rightbox:{
            flex:1,
            marginLeft:10
        },
        list:{
            flex: 1,
            flexDirection: "row",
            borderBottomColor: "#ccc",
            borderBottomWidth: 1,
            paddingTop:10,
            paddingBottom:10
        }
    })
    

    关于详情页

    //views/book/detail.js
    import React, { Component } from 'react';
    import { Text, View, ScrollView, Image, StyleSheet } from 'react-native';
    import { Icon,Header,Button } from 'react-native-elements';
    import Util from '../common/util';
    import Api from '../common/api';
    import { TouchableHighlight, TouchableOpacity } from 'react-native-gesture-handler';
    export default class BookDetail extends Component {
        constructor(props) {
            super(props);
            this.state = {
                bookID: '',
                bookData: null
            };
        }
        componentDidMount(){
            // bookID = this.props.navigation.getParam('bookID', 26378583);
            // this.setState({
            //     bookID: bookID
            // })
            this.getData();
        }
        getData(){
            //这个是从后端获取的数据
            // var url = Api.book_detail_id + this.state.bookID;
            var url = Api.book_detail_id + this.props.navigation.getParam('bookID', 26378583);
            var that = this;
            Util.getRequest(url,function(data){
                that.setState({
                    bookData: data
                })
            },function(error){
                alert(error);
            })
        }
        render(){
            var bookData = this.state.bookData;
            return (
                <ScrollView>
                    {
                        bookData != null ?
                        <View>
                                {/* <Button
                                    icon={{
                                        name: "assignment-return",
                                        size: 15,
                                        color: "white"
                                    }}
                                    onPress={() => this.props.navigation.goBack()}
                                    title="返回"
                                />   */}
    
                                <View style={styles.list}>
                                    <Image source={{ uri: bookData.images.small }} style={styles.images} />
                                    <View style={styles.rightbox}>
                                        <Text style={styles.title}>{bookData.title}</Text>
                                        <Text>价格:{bookData.price ? bookData.price : '暂无'}</Text>
                                        <Text>作者:{
                                            bookData.author.map(
                                                function (vo) {
                                                    return vo + ' ';
                                                }
                                            )
                                        }</Text>
                                        <Text>{bookData.publisher} {bookData.pubdate}</Text>
                                        <Text>{bookData.pages ? bookData.pages : '未知'} 页</Text>
                                    </View>
                                </View>
                                <View style={{ marginTop: 10 }}>
                                    <Text>图书简介</Text>
                                    <Text>{bookData.summary}</Text>
                                </View>
                                <View style={{marginTop:10}}>
                                    <Text>作者简介</Text>
                                    <Text>{bookData.author_intro}</Text>
                                </View>
                        </View>
                        : Util.loading
    
                    }
                </ScrollView>
            )
        }
    
    }
    var styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
            justifyContent: "center",
            padding: 10,
            marginTop: 0
        },
        btn: {
             100,
            height: 30
        },
        images: {  80, height: 100 },
        title: {
            fontWeight: "bold",
            color: "#f33"
        },
        rightbox: {
            flex: 1,
            marginLeft: 10
        },
        list: {
            flex: 1,
            flexDirection: "row",
            borderBottomColor: "#ccc",
            borderBottomWidth: 1,
            paddingTop: 10,
            paddingBottom: 10
        }
    })
    
  • 相关阅读:
    NW.js开发环境的搭建
    EXPORTS与MODULE.EXPORTS的区别
    搭建 webpack + React 开发环境
    require,import区别?
    数据库中图片的二进制存储和显示
    二进制图片存储问题
    单线程(Thread)与多线程的区别
    软件测试心得--悲催我
    2015年-年度总结
    人生当中第一次转正
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10917986.html
Copyright © 2011-2022 走看看