ReactNative-综合案例(02)

最近几天学了几个ReactNative组件,总觉得单纯的学几个组件进步慢,所以我打算做一些综合性的小案例,练习下实战,我从网上找到一个小案例 ,感觉挺好,也学习了很多,代码内容可能不太一样,主要区别是:我把RN官方不推荐或者已经放弃了的组件进行了替换,如果有需要的可以互相参考下

接着上篇案例开始写,这篇文章将会讲解如何编写轮播图和列表

源代码下载

首先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'
  };

  // 构造
  constructor(props){
    super(props);

    // 数据源
    var ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
    // 初始状态
    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) => {
      // 取出数组
      const dataArr = responseData[this.props.key_word];
      // 临时数组
      var tempListArr = [], adArr = [];

      // 遍历数组
      dataArr.forEach((value, index) => {
        
        if(value.hasAd == 1 || value.hasHead == 1) {
          adArr = value.ads;
        } else {
          tempListArr.push(value);
        }
      });

      // 更新状态,刷新UI
      this.setState({
        dataSource:this.state.dataSource.cloneWithRows(tempListArr),
        headerAdArr:adArr,
        flag:true
      });
    }, (error) => {
        alert(error);
    });
  }

  // 广告
  _renderHeader(){
    // 防止空数据
    if(!this.state.flag) return;

    // 容错
    if(this.state.headerAdArr.length == 0) return;

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

  /**
     * 返回具体的行
     * @private
     */
    _renderRow(rowData){
        // 0. 防止空数据
        if(!this.state.flag) return;

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

其中网络解析WYRequest抽离成一个帮助类:

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

轮播图也单独抽离为一个组件,方便直接导入:

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);
    // 初始状态
    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= />}
          activeDot={<View style= />}
          paginationStyle=
          loop
        >
          {this._renderImage()}
        </Swiper>
      </View>
    );
  }

  _renderImage(){
    // 组件数组
    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=
              defaultSource=
          />
          <View style={styles.indicatorViewStyle}>
              <Text style=>{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 {
  // 构造
  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=>{model.source}</Text>
                <Text style=>{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;

点击cell跳转到详情页面:

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=
            defaultSource=
            style={styles.imgStyle}
        />
        <View style={styles.rightViewStyle}>
            <Text
                numberOfLines={2}
            >
                {model.title}
            </Text>
            <View style={styles.rightInnerViewStyle}>
                <Text style=>{model.source}</Text>
                <Text style=>{model.ptime}</Text>
            </View>
        </View>
      </TouchableOpacity>
    );
  }

难点: 点击cell跳转详情界面,需要将WYHome.js文件当中的navigation传递到cell当中:

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

然后在cell当中就可以进行跳转了。。。。

注意

要想进行跳转必须在WYMain.js文件中,对视图进行注册

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

    // 跳转注册
    WYNewsDetail: {
      screen: WYNewsDetail,
    }
});

下一篇讲解,如何加载网页

效果图

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏偏前端工程师的驿站

WPF一步一脚印系列(1):万事起头难

  一直从事Asp.Net的开发,而C/S的开发方面简直是一片空白,于是从上星期开始就痛下决心开始学习WPF。我采取的策略是网上看基础资料+做简单的demo练习...

2489
来自专栏進无尽的文章

实践-小细节Ⅵ

有时候,UITableView 的cell个数很少,可是UITableView的headView又是一个有颜色背景的View,当我们下拉的时候,拉扯出来的区域也...

752
来自专栏学海无涯

iOS开发之XLForm的使用

在iOS开发中,开发"表单"界面,字段稍微多一点的一般都用UITableView来做,而XLForm就是这样一个框架,它是创建动态表格视图最牛逼的iOS库, 用...

4618
来自专栏葡萄城控件技术团队

七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理

系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 ...

3328
来自专栏python爬虫日记

python3下搜狗AI API实现

a、搜狗也发布了自己的人工智能 api,包括身份证ocr、名片ocr、文本翻译等API,初试感觉准确率一般般。

1893
来自专栏游戏杂谈

测试用户的网络环境

这个其实是一个hta文件,目的是测试用户本机请求资源、hosts文件、当前所处的位置。参考stone的checknetwork4qqfarm: http://c...

2711
来自专栏LeeCen

WKWebView ajax请求Cookie丢失

发现H5里面 ajax请求失败302,这可能Cookie丢失或Cookie不相同了

5741
来自专栏移动开发

一个简单的ReactNative demo

本人非前端,请轻喷 ReactNative版本:0.31 github:https://github.com/X-FAN/reactnativelear...

4883
来自专栏林德熙的博客

WPF 修改图片颜色

在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。

3891
来自专栏QQ音乐技术团队的专栏

一个循环动画引起的内存泄露问题总结

本文主要记录项目中遇到的一个内存泄露问题:由于一个循环动画引起的内存泄露,并且这个问题也是偶现的,在后面的隐藏问题里会说明。

4412

扫码关注云+社区

领取腾讯云代金券