ReactNative 项目实战 (2) ListView 使用 网络请求以及下拉刷新 (条目控件封装)

来源:互联网 发布:linux查看hadoop版本 编辑:程序博客网 时间:2024/05/30 23:03

看我的其他系列的文章
React_Native 项目实战 (1) (首页,以及页面的切换)

https://github.com/liudao01/ReactNativeProject
github地址 还在更新中

ListView 使用 网络请求以及下拉刷新

最终实现的效果图
mark

listview 以及 最热页面内容切换

现在写页面的内容 ,

知识点:

  • listivew 的使用
  • 网络数据的获取
  • 页面内容的组件封装

Listtview 的使用 看官方文档
http://reactnative.cn/docs/0.48/listviewdatasource.html#content

不要忘记引入ListView

下面是使用本地数据做的listview

mark

下面是代码

/** * Created by liuml on 2017/9/11. */import React, {Component} from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    Image,    ListView,    RefreshControl}from 'react-native';import NavigationBar from "../compoent/NavigationBar.js"import ScrollableTabView from "react-native-scrollable-tab-view"import ProjectRow from "../compoent/ProjectRow"export default class PapularPage extends Component {    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            languages: ["Android", "Ios", "Java", "React", "JS"]        };    }    render() {        return <View style={styles.container}>            <NavigationBar/>            <ScrollableTabView                tabBarBackgroundColor="#63B8FF"                tabBarActiveTextColor="#FFF"                tabBarInactiveTextColor="#F5FFFA"                tabBarUnderlineStyle={{backgroundColor: "#E7E7E7", height: 2}}>                {                    this.state.languages.map((item, i) => {                        return <PopularTab key={`tab${i}`} tabLabel={item}/>                    })                }            </ScrollableTabView>        </View>     }}class PopularTab extends Component {    //这里是Tab 的名字    static defaultProps = {        tabLable: 'Android',    }    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})//是一个优化,节省无用的UI渲染 判断前后数据是否改变 如果改变就更新        };    }    componentDidMount() {        this.setState({                dataSource: this.state.dataSource.cloneWithRows(['first', 'second', 'three'])            }        )    };    renderRow = () => {        return <Text>test</Text>    }    render() {        return <View style={styles.container}>            <ListView                dataSource={this.state.dataSource}                renderRow={this.renderRow}            ></ListView>        </View>    }}const styles = StyleSheet.create({    container: {        flex: 1    }});

解释下

componentDidMount

这个是RN加载完毕后调用的方法 生命周期

我在这里给他设置了列表的假数据 只有三条 所以在上面可以看到三条数据

其他的没什么 了 Listview的使用可以看下官方文档 比我讲的清楚

http://reactnative.cn/docs/0.48/listviewdatasource.html#content

联网请求数据返回给listview设置数据

mark

下面是代码

/** * Created by liuml on 2017/9/11. */import React, {Component} from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    Image,    ListView,    RefreshControl}from 'react-native';import NavigationBar from "../compoent/NavigationBar.js"import ScrollableTabView from "react-native-scrollable-tab-view"import ProjectRow from "../compoent/ProjectRow"export default class PapularPage extends Component {    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            languages: ["Android", "Ios", "Java", "React", "JS"]        };    }    render() {        return <View style={styles.container}>            <NavigationBar/>            <ScrollableTabView                tabBarBackgroundColor="#63B8FF"                tabBarActiveTextColor="#FFF"                tabBarInactiveTextColor="#F5FFFA"                tabBarUnderlineStyle={{backgroundColor: "#E7E7E7", height: 2}}>                {                    this.state.languages.map((item, i) => {                        return <PopularTab key={`tab${i}`} tabLabel={item}/>                    })                }            </ScrollableTabView>        </View>    }}class PopularTab extends Component {    //这里是Tab 的名字    static defaultProps = {        tabLabel: 'android',    }    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})//是一个优化,节省无用的UI渲染 判断前后数据是否改变 如果改变就更新        };    }    /*componentDidMount() {     /!*this.setState({     dataSource: this.state.dataSource.cloneWithRows(['first', 'second', 'three'])     }     )*!/     this.loadData();     };*/    //和上面一样的效果    componentDidMount = () => {        this.loadData();    }    //渲染ListView的每一行    renderRow = (obj) => {        // return <ProjectRow>{obj.full_name}</ProjectRow>        return <Text>{obj.full_name}</Text>    }    //加载数据    loadData = () => {        fetch(`https://api.github.com/search/repositories?q=${this.props.tabLabel}&sort=stars`)            .then(response => response.json()) //服务器响应response对象,继续变成json对象            .then(json => {                //更新dataSource                this.setState({                    dataSource: this.state.dataSource.cloneWithRows(json.items)                });            })            .catch((error) => {                console.error(error);            }).done();    }    render() {        return <View style={styles.container}>            <ListView                dataSource={this.state.dataSource}                renderRow={this.renderRow}            ></ListView>        </View>    }}const styles = StyleSheet.create({    container: {        flex: 1    }});

联网请求 看官方文档

http://reactnative.cn/docs/0.48/network.html#content

这样就做好了上面的gif图的效果

Listview 的item ProjectRow.js

现在数据有了,下面是做item的样式 把数据显示到item上面

先看下效果图

mark

  • 本地的数据 我把item 抽取出来 做成一个组件了

下面是item组件

/** * Created by liuml on 2017/9/14. */import React, {Component} from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    StatusBar,    Platform,    Image,    TouchableOpacity} from 'react-native';export default class ProjectRow extends Component {    static defaultProps = {        item: {}    }    render() {        var item = this.props.item;        return <View style={styles.container}>            <Text style={styles.title}>{item.full_name}</Text>            <Text style={styles.description}>{item.description}</Text>            <View style={styles.bottom}>                <View style={styles.bottomTextWrapper}>                    <Text>作者:</Text>                    {console.log(item.owner.avatar_url)}                    <Image style={{width: 22, height: 22}} source={{uri: item.owner.avatar_url}}/>                </View>                <View style={styles.bottomTextWrapper}>                    <Text>star:</Text>                    <Text>{item.stargazers_count}</Text>                </View>                <Image source={require("../../res/images/ic_unstar_transparent.png")} style={{width: 22, height: 22}}/>            </View>        </View>    }}const styles = StyleSheet.create({    container: {        flex: 1,        padding: 10,        marginLeft: 5,        marginRight: 5,        marginVertical: 5,        backgroundColor: '#FFF',        flexDirection: 'column',        borderColor: '#dddddd',        borderWidth: 0.5,        borderRadius: 2,        shadowColor: 'gray',        shadowOffset: {width: 0.5, height: 0.5},        shadowRadius: 1, //阴影半径        shadowOpacity: 0.4,        elevation: 2 //Android 投影    },    title: {        fontSize: 16    },    description: {        fontSize: 14,        marginBottom: 2,        color: '#757575'    },    bottom: {        flexDirection: 'row',        alignItems: 'center',        justifyContent: 'space-between'    },    bottomTextWrapper: {        flexDirection: 'row',        alignItems: 'center'    }})

解释下: 没啥好说的 就是UI布局 做多了都一样 下面是几个属性 解释下

borderColor : 设置边框颜色

borderWidth : 属性设置所有四个边框的宽度。

borderRadius : 边框圆角效果

shadowColor:’gray’,//阴影颜色

shadowOffset:{width:0.5,height:0.5},//shadowoffset 四周阴影

shadowRadius:1, //阴影半径

shadowOpacity:0.4,//阴影不透明度

elevation:2 //Android 投影

还有就是PopularPage.js 里面只改动了一行代码

    //渲染ListView的每一行    renderRow = (obj) => {        return <ProjectRow item={obj}></ProjectRow>        // return <Text>{obj.full_name}</Text>    }

这样就做好了上面的gif图的效果

listview 的加载动画以及下拉刷新

看下文档

https://reactnative.cn/docs/0.48/refreshcontrol.html#content

搜索 RefreshControl 这个就是刷新的使用

/** * Created by liuml on 2017/9/11. */import React, {Component} from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    Image,    ListView,    RefreshControl}from 'react-native';import NavigationBar from "../compoent/NavigationBar.js"import ScrollableTabView from "react-native-scrollable-tab-view"import ProjectRow from "../compoent/ProjectRow"export default class PapularPage extends Component {    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            languages: ["Android", "Ios", "Java", "React", "JS"]        };    }    render() {        return <View style={styles.container}>            <NavigationBar/>            <ScrollableTabView                tabBarBackgroundColor="#63B8FF"                tabBarActiveTextColor="#FFF"                tabBarInactiveTextColor="#F5FFFA"                tabBarUnderlineStyle={{backgroundColor: "#E7E7E7", height: 2}}>                {                    this.state.languages.map((item, i) => {                        return <PopularTab key={`tab${i}`} tabLabel={item}/>                    })                }            </ScrollableTabView>        </View>    }}class PopularTab extends Component {    //这里是Tab 的名字    static defaultProps = {        tabLabel: 'android',    }    // 构造    constructor(props) {        super(props);        // 初始状态        this.state = {            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),//是一个优化,节省无用的UI渲染 判断前后数据是否改变 如果改变就更新            isLoading: true        };    }    /*componentDidMount() {     /!*this.setState({     dataSource: this.state.dataSource.cloneWithRows(['first', 'second', 'three'])     }     )*!/     this.loadData();     };*/    //和上面一样的效果    componentDidMount = () => {        this.loadData();    }    //渲染ListView的每一行    renderRow = (obj) => {        return <ProjectRow item={obj}></ProjectRow>        // return <Text>{obj.full_name}</Text>    }    //加载数据    loadData = () => {        this.setState({isLoading: true});        fetch(`https://api.github.com/search/repositories?q=${this.props.tabLabel}&sort=stars`)            .then(response => response.json()) //服务器响应response对象,继续变成json对象            .then(json => {                //更新dataSource                this.setState({                    dataSource: this.state.dataSource.cloneWithRows(json.items),                    isLoading: false,                });            })            .catch((error) => {                console.error(error);            }).done();    }    handleRefresh = () => {        this.loadData();    }    render() {        return <View style={styles.container}>            <ListView                dataSource={this.state.dataSource}                renderRow={this.renderRow}                refreshControl={                    <RefreshControl                        refreshing={this.state.isLoading}                        tintColor="#63B8FF"                        title="正在加载..."                        titleColor="#63B8FF"                        colors={['#63B8FF']}                    />                }            ></ListView>        </View>    }}const styles = StyleSheet.create({    container: {        flex: 1    }});

解释

  • isLoading 用来判断是否显示对话框

- return 是把每个item的数据传到 ProjectRow里面去

最终实现的效果图
mark

阅读全文
0 0
原创粉丝点击