ReactNative-綜合案例(02)

本文出自:我的個(gè)人博客:http://www.cenzhijun.top/
最近幾天學(xué)了幾個(gè)ReactNative組件,總覺(jué)得單純的學(xué)幾個(gè)組件進(jìn)步慢仗处,所以我打算做一些綜合性的小案例泻帮,練習(xí)下實(shí)戰(zhàn)党晋,我從網(wǎng)上找到一個(gè)小案例
斧抱,感覺(jué)挺好,也學(xué)習(xí)了很多掐禁,代碼內(nèi)容可能不太一樣怜械,主要區(qū)別是:我把RN官方不推薦或者已經(jīng)放棄了的組件進(jìn)行了替換颅和,如果有需要的可以互相參考下

接著上篇案例開始寫,這篇文章將會(huì)講解如何編寫輪播圖和列表

源代碼下載

首先WYHome.js代碼如下:

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
    ListView
} from 'react-native';

import Request from '../Utils/WYRequest'
import WYSwiper from './Swiper/WYHomeSwiper'
import WYNewsCell from './WYNewsCell'

export default class WYHome extends Component {
  static defaultProps = {
    api_url: 'http://c.m.163.com/nc/article/headline/T1348647853363/0-20.html?from=toutiao&fn=1&prog=LTitleA&passport=&devId=nTM86EPlcxZu09VdpTEh6aR3%2B%2FQX6x8vHBD3ne3k5bbgOrg%2FIP5DcguSDmtYyWbs&offset=0&size=20&version=14.0&spever=false&net=wifi&lat=DUH4Hf95lyIDaAI03C3RSA%3D%3D&lon=HJ4tj6FL5wRHQxcf5GLEcg%3D%3D&ts=1470728804&sign=1H8K3yy9bMXakmxAlZ9P86meraJtjKQFz5vJuwhjNyl48ErR02zJ6%2FKXOnxX046I&encryption=1&canal=appstore',
    key_word: 'T1348647853363'
  };

  // 構(gòu)造
  constructor(props){
    super(props);

    // 數(shù)據(jù)源
    var ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
    // 初始狀態(tài)
    this.state = {

      dataSource:ds,
      // 廣告
      headerAdArr:[],

      // 判斷是否為空
      flag:false
    };
  }
  render() {
    return (
      <ListView 
        dataSource={this.state.dataSource}
        renderHeader={this._renderHeader.bind(this)}
        renderRow={this._renderRow.bind(this)}
      >
      
      </ListView>
    );
  }

  componentDidMount() {
    Request.get(this.props.api_url, (responseData) => {
      // 取出數(shù)組
      const dataArr = responseData[this.props.key_word];
      // 臨時(shí)數(shù)組
      var tempListArr = [], adArr = [];

      // 遍歷數(shù)組
      dataArr.forEach((value, index) => {
        
        if(value.hasAd == 1 || value.hasHead == 1) {
          adArr = value.ads;
        } else {
          tempListArr.push(value);
        }
      });

      // 更新?tīng)顟B(tài)缕允,刷新UI
      this.setState({
        dataSource:this.state.dataSource.cloneWithRows(tempListArr),
        headerAdArr:adArr,
        flag:true
      });
    }, (error) => {
        alert(error);
    });
  }

  // 廣告
  _renderHeader(){
    // 防止空數(shù)據(jù)
    if(!this.state.flag) return;

    // 容錯(cuò)
    if(this.state.headerAdArr.length == 0) return;

    return(
      <WYSwiper dataArr={this.state.headerAdArr}></WYSwiper>
    );
  }

  /**
     * 返回具體的行
     * @private
     */
    _renderRow(rowData){
        // 0. 防止空數(shù)據(jù)
        if(!this.state.flag) return;

        return(
            <WYNewsCell model={rowData} navigator={this.props.navigation}/>
        );
    }
}

其中網(wǎng)絡(luò)解析WYRequest抽離成一個(gè)幫助類:

module.exports = {
    /**
     * 基于fetch的get方法
     * @method post
     * @param {string} url
     * @param {function} callback 請(qǐng)求成功回調(diào)
     */
    get: function(url, successCallback, failCallback){
        fetch(url)
            .then((response) => response.json())
            .then((responseText) => {
                successCallback(responseText);
            })
            .catch(function(err){
                failCallback(err);
            });
    }
};

輪播圖也單獨(dú)抽離為一個(gè)組件融虽,方便直接導(dǎo)入:

import React, { Component } from 'react'
import {
  Text,
  View,
  Image,
  Dimensions
} from 'react-native'

import Swiper from 'react-native-swiper'
const { width } = Dimensions.get('window');

export default class extends Component {
  static defaultProps = {
      dataArr: []
  };

  constructor(props) {
    super(props);
    // 初始狀態(tài)
    this.state = {
        currentTitle: ''
    };
  }

  render() {
    return (
      <View>
        <Swiper
          style={styles.wrapper}
          height={170}
          onMomentumScrollEnd={(e, state, context) => this.setState({
              // currentTitle: dataArr[state.index].title
          })}
          dot={<View style={{backgroundColor: 'rgba(255,255,255,1)', width: 5, height: 5, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
          activeDot={<View style={{backgroundColor: 'orange', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
          paginationStyle={{
        bottom: 10, left: null, right: 10
        }}
          loop
        >
          {this._renderImage()}
        </Swiper>
      </View>
    );
  }

  _renderImage(){
    // 組件數(shù)組
    var itemArr = [];

    const dataArr = this.props.dataArr;
    dataArr.forEach((value, index) => {
      itemArr.push(
        <View key={index} style={styles.slide}>
          <Image
              resizeMode='stretch'
              style={styles.image}
              source={{uri: value.imgsrc}}
              defaultSource={{uri: 'placeholder'}}
          />
          <View style={styles.indicatorViewStyle}>
              <Text style={{color:'#fff'}}>{value.title}</Text>
          </View>
        </View>
      );
    });

    // 返回組件
    return itemArr;
  }
}

const styles = {
  wrapper: {
  },

  slide: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'transparent'
  },

  slide1: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#9DD6EB'
  },

  slide2: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#97CAE5'
  },

  slide3: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#92BBD9'
  },

  text: {
    color: '#fff',
    fontSize: 30,
    fontWeight: 'bold'
  },

  image: {
    width,
    flex: 1
  },

  indicatorViewStyle:{
     width,
     height:36,
     backgroundColor:'rgba(0,0,0, 0.4)',
     position:'absolute',
     left:0,
     bottom:0,

     justifyContent:'center',
     paddingLeft:5
  }
};

自定義cellWYNewsCell.js代碼如下:

import React, { Component, PropTypes } from 'react';
import {
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    Image,
    PixelRatio
} from 'react-native';

var Dimensions = require('Dimensions');
var {width, height} = Dimensions.get('window');

export default class WYNewsCell extends Component {
  // 構(gòu)造
  constructor(props){
    super(props);

    this.state = {
      model: this.props.model,
      navigator: this.props.navigator,
    };
  }
  render() {
    var model = this.state.model;
    var hahah = this.state.navigator;

    return (
      <TouchableOpacity style={styles.cellStyle} onPress={() => {
        hahah.navigate('WYNewsDetail', {title: model.title});
      }}>
        <Image
            source={ {uri: model.imgsrc} }
            defaultSource={ {uri: 'placeholder'} }
            style={styles.imgStyle}
        />
        <View style={styles.rightViewStyle}>
            <Text
                numberOfLines={2}
            >
                {model.title}
            </Text>
            <View style={styles.rightInnerViewStyle}>
                <Text style={{color:'red', fontSize:14}}>{model.source}</Text>
                <Text style={{color:'#333', fontSize:14}}>{model.ptime}</Text>
            </View>
        </View>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  cellStyle:{
    borderBottomWidth: 1/PixelRatio.get(),
    borderBottomColor: '#666',

    flexDirection:'row',
    padding:10
  },

  imgStyle:{
    width:90,
    height:90,
    borderRadius:5,
    marginRight:10
  },

  rightViewStyle:{
    flex:1,
    justifyContent:'space-around'
  },

  rightInnerViewStyle:{
    flexDirection:'row',
    justifyContent:'space-between'
  }
});

module.exports = WYNewsCell;

點(diǎn)擊cell跳轉(zhuǎn)到詳情頁(yè)面:

render() {
    var model = this.state.model;
    var hahah = this.state.navigator;

    return (
      <TouchableOpacity style={styles.cellStyle} onPress={() => {
        hahah.navigate('WYNewsDetail', {title: model.title});
      }}>
        <Image
            source={{uri: model.imgsrc}}
            defaultSource={{uri: 'placeholder'}}
            style={styles.imgStyle}
        />
        <View style={styles.rightViewStyle}>
            <Text
                numberOfLines={2}
            >
                {model.title}
            </Text>
            <View style={styles.rightInnerViewStyle}>
                <Text style={{color:'red', fontSize:14}}>{model.source}</Text>
                <Text style={{color:'#333', fontSize:14}}>{model.ptime}</Text>
            </View>
        </View>
      </TouchableOpacity>
    );
  }

難點(diǎn):
點(diǎn)擊cell跳轉(zhuǎn)詳情界面,需要將WYHome.js文件當(dāng)中的navigation傳遞到cell當(dāng)中:

<WYNewsCell model={rowData} navigator={this.props.navigation}/>

然后在cell當(dāng)中就可以進(jìn)行跳轉(zhuǎn)了灼芭。。般又。彼绷。

注意

要想進(jìn)行跳轉(zhuǎn)必須在WYMain.js文件中,對(duì)視圖進(jìn)行注冊(cè)

const StackNavigators = StackNavigator({
    TabNav: {
      screen: TabNav,
    },

    // 跳轉(zhuǎn)注冊(cè)
    WYNewsDetail: {
      screen: WYNewsDetail,
    }
});

下一篇講解茴迁,如何加載網(wǎng)頁(yè)

效果圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寄悯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子堕义,更是在濱河造成了極大的恐慌猜旬,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倦卖,死亡現(xiàn)場(chǎng)離奇詭異洒擦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)怕膛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門熟嫩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人褐捻,你說(shuō)我怎么就攤上這事掸茅。” “怎么了柠逞?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵昧狮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我板壮,道長(zhǎng)逗鸣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任个束,我火速辦了婚禮慕购,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茬底。我一直安慰自己沪悲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布阱表。 她就那樣靜靜地躺著殿如,像睡著了一般贡珊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涉馁,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天门岔,我揣著相機(jī)與錄音,去河邊找鬼烤送。 笑死寒随,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帮坚。 我是一名探鬼主播妻往,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼试和!你這毒婦竟也來(lái)了讯泣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤阅悍,失蹤者是張志新(化名)和其女友劉穎好渠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體节视,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拳锚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肴茄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌畅。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寡痰,靈堂內(nèi)的尸體忽然破棺而出抗楔,到底是詐尸還是另有隱情,我是刑警寧澤拦坠,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布连躏,位于F島的核電站,受9級(jí)特大地震影響贞滨,放射性物質(zhì)發(fā)生泄漏入热。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一晓铆、第九天 我趴在偏房一處隱蔽的房頂上張望勺良。 院中可真熱鬧,春花似錦骄噪、人聲如沸尚困。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)事甜。三九已至谬泌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逻谦,已是汗流浹背掌实。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邦马,地道東北人贱鼻。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像滋将,于是被迫代替她去往敵國(guó)和親忱嘹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,513評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)耕渴、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評(píng)論 4 62
  • 楔子 中醫(yī)世家獨(dú)女齿兔?清華大學(xué)高材生橱脸?古武界少主?
    秦馥萱閱讀 185評(píng)論 1 1
  • 我是一片落葉 是秋風(fēng)把我 吹到這個(gè)地方 我還沒(méi)有死 我還不會(huì)死 我只是漸漸凋零 衰草里再不見(jiàn) 蟋蟀的長(zhǎng)吟 月光在雨...
    一默1520閱讀 358評(píng)論 4 9
  • 一直覺(jué)得這世界上的告別儀式挺多的分苇,比如喝一場(chǎng)大酒添诉,來(lái)一場(chǎng)旅行,或者情不自禁的在車站大哭一場(chǎng)医寿±父埃可是后來(lái)才知道,人生中...
    RebornF閱讀 94評(píng)論 0 1