【水滴石穿】react-native-book

博客推荐了学习地址https://ke.qq.com/webcourse/index.html,博主打算据此做App。还分享了GitHub上开源项目地址https://github.com/linchengzzz/rnTest,并对项目进行分析,指出运行效果可能存在接口问题,还将查看main.js并分析对应页面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

//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 />
        );
    }
}

分析对应页面
1037363-20190524141151699-2123570060.png

//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:{
        width: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:{
        width:100,
        height:30
    },
    images: { width: 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: {
        width: 100,
        height: 30
    },
    images: { width: 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
    }
})

转载于:https://www.cnblogs.com/smart-girl/p/10917986.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值