ReactNative Project Practice (2) ListView uses network requests and drop-down refreshes (Entry Control Encapsulation)

Keywords: React Android JSON network

ListView uses network requests and drop-down refreshes

The final result

listview and Hottest Page Content Switching

Now write the content of the page.

Knowledge points:

  • Use of listivew
  • Acquisition of Network Data
  • Component Encapsulation of Page Content

Use Listtview to see official documents
http://reactnative.cn/docs/0.48/listviewdatasource.html#content

Don't forget to introduce ListView

Here's a list view using local data

Here's the code

/**
 * 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 {


    // structure
    constructor(props) {
        super(props);
        // Initial state
        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 {

    //Here's Tab's name.
    static defaultProps = {
        tabLable: 'Android',
    }
    // structure
    constructor(props) {
        super(props);
        // Initial state
        this.state = {
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})//Is an optimization that saves useless UI rendering to determine whether data changes before and after it is updated if it changes
        };
    }

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

Under interpretation

componentDidMount

This is the method lifecycle that RN calls after loading.

I've set him a list of three false data here, so you can see three data on it.

There's nothing else about the use of Listview. You can see that the official documents are clearer than I said.

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

The networking request data is returned to the listview settings data

Here's the code

/**
 * 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 {


    // structure
    constructor(props) {
        super(props);
        // Initial state
        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 {

    //Here's Tab's name.
    static defaultProps = {
        tabLabel: 'android',
    }
    // structure
    constructor(props) {
        super(props);
        // Initial state
        this.state = {
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})//Is an optimization that saves useless UI rendering to determine whether data changes before and after it is updated if it changes
        };
    }

    /*componentDidMount() {
     /!*this.setState({
     dataSource: this.state.dataSource.cloneWithRows(['first', 'second', 'three'])
     }
     )*!/
     this.loadData();
     };*/

    //The same effect as above
    componentDidMount = () => {
        this.loadData();
    }

    //Render each line of ListView
    renderRow = (obj) => {
        // return <ProjectRow>{obj.full_name}</ProjectRow>
        return <Text>{obj.full_name}</Text>
    }


    //Loading data
    loadData = () => {

        fetch(`https://api.github.com/search/repositories?q=${this.props.tabLabel}&sort=stars`)
            .then(response => response.json()) //The server responds to the response object and continues to become a json object
            .then(json => {
                //Update 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
    }
});

Online Request See Official Documents

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

In this way, the effect of the gif diagram above is completed.

Listview's item ProjectRow.js

Now that the data is available, here's how to do item to display the data on item

Look at the effect first.

  • Local data I extracted item to make a component

Here's the item component

/**
 * 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>author:</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, //Shadow radius
        shadowOpacity: 0.4,
        elevation: 2 //Android projection

    },
    title: {
        fontSize: 16

    },
    description: {
        fontSize: 14,
        marginBottom: 2,
        color: '#757575'

    },
    bottom: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between'
    },
    bottomTextWrapper: {
        flexDirection: 'row',
        alignItems: 'center'
    }
})

Interpretation: What's not to say is that UI layouts are all the same. Here are a few attributes to explain.

borderColor: Set the border color

borderWidth: Property sets the width of all four borders.

borderRadius: Border Corner Effect

shadowColor:'gray', // Shadow color

Shadow Offset: {width: 0.5, height: 0.5}, //shadow off set shadows around

Shadow Radius: 1, // Shadow Radius

Shadow Opacity: 0.4, // Shadow Opacity

Elevation: 2//Android projection

And there's only one line of code changed in PopularPage.js.

    //Render each line of ListView
    renderRow = (obj) => {
        return <ProjectRow item={obj}></ProjectRow>
        // return <Text>{obj.full_name}</Text>
    }

In this way, the effect of the gif diagram above is completed.

listview loaded animation and drop-down refresh

Look at the document

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

Search RefreshControl This is the use of refresh

/**
 * 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 {


    // structure
    constructor(props) {
        super(props);
        // Initial state
        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 {

    //Here isTab Name
    static defaultProps = {
        tabLabel: 'android',
    }
    // structure
    constructor(props) {
        super(props);
        // Initial state
        this.state = {
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),//Is an optimization, saving uselessUIRendering judges whether the data before and after changes and updates if changes occur
            isLoading: true
        };
    }

    /*componentDidMount() {
     /!*this.setState({
     dataSource: this.state.dataSource.cloneWithRows(['first', 'second', 'three'])
     }
     )*!/
     this.loadData();
     };*/

    //The same effect as above
    componentDidMount = () => {
        this.loadData();
    }

    //Rendering ListView Every row
    renderRow = (obj) => {
        return <ProjectRow item={obj}></ProjectRow>
        // return <Text>{obj.full_name}</Text>
    }


    //Loading data
    loadData = () => {
        this.setState({isLoading: true});
        fetch(`https://api.github.com/search/repositories?q=${this.props.tabLabel}&sort=stars`)
            .then(response => response.json()) //Server response response Object, continue to become json object
            .then(json => {
                //To update 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="Loading..."
                        titleColor="#63B8FF"
                        colors={['#63B8FF']}
                    />
                }
            ></ListView>
        </View>
    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1
    }
});

explain

  • isLoading is used to determine whether a dialog box is displayed or not

- return is the transfer of data from each item to Project Row.

The final result

Posted by aff on Fri, 24 May 2019 16:02:01 -0700