React Native: Load news list

Label and content page linkage

The last section (React Native: custom view) makes the click tag automatically move, and the difference is linked with the view below.

First create NewsList.js :

import React from 'react'
import {
    View,
    Text,
    ListView,
    Image,
    StyleSheet,
    Dimensions
} from 'react-native'
const {width, height} = Dimensions.get('window')

export default class NewsList extends React.Component {
    render() {
        const {style} = this.props
        return (
            <View style={[styles.view,style]}>

            </View>
        )
    }
}

const styles = StyleSheet.create({
    view: {
        flex: 1,
        backgroundColor:'red'
    }
})

and then introduce Home.js, then join ScrollView, now Home.js@@@ @redner()This is the case, cccView, which we added here, is called """" 我们在后文中称为 NewsScrollView

render() {
        return (
            <View style={styles.view}>
                <NavigationBar
                    title=_getNewsLists()Method: @@ @@Creates a corresponding number of views based on the returned data, giving random colors a convenient view. unLeftImage={true}
                />

                <SegmentedView
                    ref="SegmentedView"
                    list={this.state.list}
                    style={{height: 30}}
                />

                <ScrollView
                    style={styles.view}
                    ref="ScrollView"
                    horizontal={true}
                    showsHorizontalScrollIndicator={false}
                    pagingEnabled={true}
                >
                    { this._getNewsLists()}
                </ScrollView>
           </View>
        )
    }

First set the slide 方法:

_getNewsLists() {
    let lists = []
    if (this.state.list) {
        for (let index in this.state.list) {
            let dic = this.state.list[index]
            lists.push(
                <NewsList
                    key={index}
                    style={{backgroundColor:'#' + this._getColor('',0), width: width, height: height - 49 - 64 - 30}}
                    dic={dic}
                />
            )
        }
    }

    return lists
}

_getColor(color, index) {

    index ++

    if (index == 7) {
        return color
    }

    color = color + '0123456789abcdef'[Math.floor(Math.random()*16)]
    return  this._getColor(color, index)
}

NewsScrollView

Let the label move.

让标签跟着移动。

中的 方法的实现单独写到一个方法里,然后在这里调用:

_moveTo(index) {
    const { list } = this.props  

    this.state.selectItem && this.state.selectItem._unSelect()
    this.state.selectItem = this.refs[index]


    if (list.length > maxItem) {
        let meiosis = parseInt(maxItem / 2)
        this.refs.ScrollView.scrollTo({x: (index - meiosis < 0 ? 0 : index - meiosis > list.length - maxItem ? list.length - maxItem : index - meiosis ) * this.state.itemWidth, y: 0, animated: true})
    }
}

加了一个 ,原来我们获取 是在 中计算的,但是在渲染的过程中无法调用 ,我们把计算 的方法移动到 :

componentWillReceiveProps(props) {
    const { list } = props  
    if (!list || list.length == 0) return

    
    let itemWidth = width / list.length

    if (list.length > maxItem) {
        itemWidth = width / maxItem
    }

    this.setState({
        itemWidth
    })
}

方法会在属性更新后调用,参数 是新的属性。

只会让上一个选中的变为未选中,新的标签并没有变为选中,这是因为选中状态只在标签被点击的时候进行了设置,我们需要给 添加一个选中的方法 :

 _select() {
    this.setState({
        isSelect: true
    })
}

进行调用:

this.state.selectItem && this.state.selectItem._unSelect()
this.state.selectItem = this.refs[index]
this.state.selectItem._select()

上面的 可以正常运行了。

@@@ 滑动到对应的位置,我们需要给 //Get the incoming array 加入一个回调函数,在标签被点击的时候调用返回点击的 index

<SegmentedView
    ref="SegmentedView"
    list={this.state.list}
    style={{height: 30}}
    selectItem={(index) => {
        this.refs.ScrollView.scrollTo({x: width * index, y: 0, animated: true})
    }}
/>

, we will find that we added this.state to a

_getItems() {
    const { list, selectItem } = this.props  itemWidth, we got if (!list || list.length == 0) return []

    let items = []
    for (let index in list) {
        let dic = list[index]
        items.push(
            <Item
                ref={index}
                key={index}
                isSelect={index == 0}
                itemHeight={this.state.itemHeight}
                itemWidth={this.state.itemWidth}
                dic={dic}
                onPress={() => {
                    this._moveTo(index)
                    selectItem && selectItem(index)
                }}
            />
        )
    }



    return items
}

itemWidth

is calculated in

_getItems()SetState() cannot be called during rendering, we calculate itemWidth Move to:

, but
_getNewsLists() {
    let lists = []
    if (this.state.list) {
        for (let index in this.state.list) {
            let dic = this.state.list[index]
            lists.push(
                <NewsList
                    key={index}
                    style={{backgroundColor:'white'}}
                    dic={dic}
                    isRequest={index == 0}
                />
            )
        }
    }

    return lists
}

//Get the incoming array // Calculate the width of each tag 进行请求数据:


 componentWillReceiveProps(props)The method will be called after the property is updated, parameter @ @@@props is a new attribute.  Now running will find that the click tag can change the status of the tag normally, but dragging 
    this.state = {
        page: 1,
        rn: 1,
    };
}


componentDidMount() {
    if (!this.props.isRequest) return
    this._onRefresh()
}

 _onRefresh(page) {
    if (this.props.dic) {
        let url = 'http://api.iapple123.com/newspush/list/index.html?clientid=1114283782&v=1.1&type='
            + this.props.dic.NameEN
            + '&startkey=&newkey=&index='
            + (page ? page : this.state.page)
            + '&size=20&ime=6271F554-7B2F-45DE-887E-4A336F64DEE6&apptypeid=ZJZYIOS1114283782&rn='
            + this.state.rn

        LOG('url=》', url)
        fetch(url, {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
        })
            .then((res) => {

                res.json()
                    .then((json) => {
                        LOG('GET SUCCESSED then =>', url, json)

                        })
                    })
                    .catch((e) => {
                        LOG('GET ERROR then =>', url, e)

                    })
            })
            .catch((error) => {

                LOG('GET ERROR=>', url, '==>', error)
            })
    }
}

NewsScrollViewItem: and then ,然后去 _moveTo(index) Call:

will only make the previous selected unselected, the new tag does not become selected, this Because the selected state is only set when the tag is clicked, we need to add a selected method to
render() {
    const {style} = this.props
    return (
        <View style={[styles.view,style]}>
            <ListView
                style={{flex:1}}
                dataSource= Now run the slide  //设置数据源
                renderRow=NewsScrollView The above cell
            />
        </View>
    )
}

SegmentedView Finally set the click tag to let renderRow:

can run normally.
NewsScrollView slide to the corresponding location, we need to add a callback function to var getRowData = (dataBlob, sectionID, rowID) => {

        return dataBlob[sectionID][rowID]
    };
    SegmentedView, and call back when the tag is clicked. this.state = {

        page: 1,
        rn: 1,
        dataSource: new ListView.DataSource({
            getRowData: getRowData,
            rowHasChanged: (r1, r2) => r1 !== r2,
        }),
    };

    this.renderRow = this.renderRow.bind(this)

}



renderRow(rowData, rowID, highlightRow) {
    return (
        <View />
    )
}

SegmentedView

Calling:

//Get the incoming array

Loading the news list The first page of data loading News list The first page of data In 数据发现只有一个数组,轮播图是取了前四个,剩下的根据 Home.js, we have passed the data to

NewsList Then go to 加入

, and we pass in a parameter to identify whether it is the first page, and only load the data of the first page initially. Also convenient for debugging:
let list = json.NewsList

let swipers = []
let news = []

for (let index in list) {
    let dic = list[index]
    index < 4 ? swipers.push(dic) : news.push(dic)
}

news.splice(0, 0, swipers)


this.setState({
    dataSource: this.state.dataSource.cloneWithRows(news)
})

NewsList.js// Constructconstructor(props) {     Super(props);

Request data:
[
    [
        {},
        {}
    ],

    {},
    {}
}

// Initial state After requesting data, we need to use 处理数据

ListView

(official document) to display, so import
if (Object.prototype.toString.call(rowData) === '[object Array]') {
    return (
        <CarousePicture
            index={2}
            ref="ScrollView"
            rowData={rowData}
            style={{width, height: 200}}
            touchIn={this.props.touchIn}
        >
        </CarousePicture>
    )
}

ListViewrender()Join: {this.state.dataSource}//Set the data source {this.renderRow}//Set @@ @@ Then join

, Then go to

dataSource

and

// constructconstructor(props) {     Super(props);// Initial state 上两个 Run effect 重叠时,处于顶部的 The interface we are going to do is like this 滑动事件不会响应,因为底部的 It can be seen from the above picture that the news is divided into 3 styles, carousel Figure, there is a picture and two or three pictures. 进行了响应并拦截了事件,我们需要在手指接触到轮播图的时候禁用底部 Next, the data is parsed. After parsing 的滑动属性,再手指离开的时候再进行恢复,所以还需要去 json, the data is found to have only one array. The carousel is taken in the first four, and the rest is based on

 _getNewsLists() {
    let lists = []
    if (this.state.list) {
        for (let index in this.state.list) {
            let dic = this.state.list[index]
            lists.push(
                <NewsList
                    key={index}
                    style={{backgroundColor:'white', width: width, height: height - 64 - 49 - 30}}
                    dic={dic}
                    isRequest={index == 0}
                    touchIn={(scrollEnabled) => {
                        this.refs.ScrollView.setNativeProps({scrollEnabled: !scrollEnabled})
                    }}
                />
            )
        }
    }
  return lists
}

ImagesList 的个数来区分:

Judging by the number,
let imagesList = rowData.ImagesList

if (imagesList && imagesList.length == 1) {
    return (
        <TouchableOpacity style={{width,  backgroundColor:'white'}}>
            <View
                style={{width, backgroundColor:'white', flexDirection:'row', justifyContent:'space-between', flex:1}}>
                <Image
                    resizeMode="cover"
                    style={{marginTop: 10, marginBottom:10, marginLeft: 10, width: 80, height: 80, backgroundColor:'#EEEEEE'}}
                    source={{uri:imagesList[0].ImgPath}}
                />

                <View
                    style={{ marginRight: 10,backgroundColor:'white', marginTop: 10, height: 80, width: width - 110}}
                >
                    <Text>{rowData.Title}</Text>
                    <View style={{flex:1, flexDirection: 'row', justifyContent: 'space-between'}}>
                        <Text style={{marginTop:10, fontSize: 13, color: '#999999'}}>{rowData.Source}</Text>
                        <Text style={{marginRight:0,marginTop:10,fontSize: 13, color: '#999999'}}>{rowData.PublishTime}</Text>
                    </View>
                </View>
            </View>
            <View style={{width, height:1, backgroundColor: '#EEEEEE'}}></View>
        </TouchableOpacity>
    )
}

let images = []

for (let index in imagesList) {
    let dic = imagesList[index]
    images.push(
        <Image
            resizeMode="cover"
            key={index}
            style={{marginRight: 10, marginLeft: index == 0 ? 10 : 0, marginTop:10, marginBottom: 10,flex:1, height: 90}}
            source={{uri:dic.ImgPath}}
        />
    )
}

return (
    <TouchableOpacity style={{width,  backgroundColor:'white'}}>

        <View style={{width,backgroundColor:'white'}}>
            <Text style={{marginLeft: 10, marginTop: 10}}>{rowData.Title}</Text>
        </View>
        <View style={{flexDirection:'row'}}>
            {images}
        </View>
        <View style={{flex:1, flexDirection: 'row', justifyContent: 'space-between'}}>
            <Text style={{marginLeft: 10, marginBottom: 10,fontSize: 13, color: '#999999'}}>{rowData.Source}</Text>
            <Text style={{marginRight:10,fontSize: 13, marginBottom: 10,color: '#999999'}}>{rowData.PublishTime}</Text>
        </View>
        <View style={{width, height:1, backgroundColor: '#EEEEEE'}}></View>
    </TouchableOpacity>
)

.then((json) => { 没有进行整理,所以看着比较乱,正式开发中应该整理到 news The data structure is:

Join

Then go to

renderRow

Process data

If it is an array, then return to the carousel:

The carousel here is