美文网首页
RN学习-ListView列表

RN学习-ListView列表

作者: 马戏团小丑 | 来源:发表于2017-10-23 17:52 被阅读24次

    以下是发现模块的代码Discover.js

    /**
     * @providesModule Discover
     */
    import React, {Component} from 'react'
    
    // 2.导入常用组件,注册组件,样式组件,View组件,Text组件
    import
    {
        AppRegistry,
        StyleSheet,
        Text,
        View,
        Image
    }from 'react-native'
    // 网络请求
    var discoverData = require('../Res/discoverData.json');
    
    // 导入自定义分组ListView
    import CommonGroupListViewHeader from 'CommonGroupListViewHeader'
    import Common from 'Common'
    import CommonNavigationBar from 'CommonNavigationBar'
    import DiscoverScrollCell from  'DiscoverScrollCell'
    import DiscoverVideoCell from  'DiscoverVideoCell'
    import VideoView from 'VideoView'
    
    // 3.自定义 程序入口组件([[UIView alloc] init])
    export default class Discover extends Component {
    
        constructor(props){
            super(props);
            var groups = [];
            // 加载第0组
            this.setupGroup0(groups);
            // 加载第1组
            this.setupGroup1(groups);
            // 加载第2组
            this.setupGroup2(groups)
            this.state = {
                groups:groups //创建数据源,但还没有给它传递数据,使用state保存数据源,因为数据源的数据改变的时候,需要刷新界面
            }
        }
    
        setupGroup0(groups){
            var section = discoverData[0];
            var sectionData = section.sData; // sData rData 是json数据的数据字段
            var rowDatas = section.rData;
    
            var allRowData = [];
            rowDatas.forEach((rowData,i)=>{
                var item = new CommonGroupListViewHeader.CommonArrowRowItem('',rowData.name,rowData.disc);
                allRowData.push(item);
            });
    
            var group0 = new CommonGroupListViewHeader.CommonGroupItem(allRowData,sectionData.height);
            groups.push(group0);
        }
    
        setupGroup1(groups){
    
            var section = discoverData[1];
            var sectionData = section.sData;
            var rowDatas = section.rData;
    
            var item0 = new CommonGroupListViewHeader.CommonArrowRowItem('',sectionData.name,sectionData.disc);
    
            var item1 = new CommonGroupListViewHeader.CommonRowItem();
            item1.customData = rowDatas[0];
            item1.customCellType = DiscoverScrollCell;
    
            var group1 = new CommonGroupListViewHeader.CommonGroupItem([item0,item1],sectionData.height);
            groups.push(group1);
        }
    
    
        setupGroup2(groups){
    
            var section = discoverData[2];
            var sectionData = section.sData;
            var rowDatas = section.rData;
            var allRowData = [];
            var item0 = new CommonGroupListViewHeader.CommonArrowRowItem('',sectionData.name);
            allRowData.push(item0); // 给allRowData数据源加入头部数据
    
            rowDatas.forEach((rowData,i)=>{  // 遍历rowDatas组数据得出行数据,加入总数据rowDatas中
                var item = new CommonGroupListViewHeader.CommonRowItem();
                item.customData = rowData;
                item.customCellType = DiscoverVideoCell;
                item.route = {
                    component:VideoView,
                    videoUri:rowData.video
                }
                allRowData.push(item);  //给allRowData数据源加入每个cell数据
            });
    
            var group1 = new CommonGroupListViewHeader.CommonGroupItem(allRowData,sectionData.height);
            groups.push(group1);
        }
        render(){
    
            return (
                <View>
                    <CommonNavigationBar
                        titleView={this.renderTitleView()}
                    />
                    <CommonGroupListViewHeader.CommonGroupListView groups={this.state.groups}
                                                                   groupListViewStyle={{backgroundColor:Common.bgColor}}
                                                                   navigator={this.props.navigator}
                                                                   titleStyle={{fontSize:18}}
                                                                   subTitleStyle={{color:'rgb(80,80,80)'}}
    
                    />
                </View>
            )
        }
    
        renderTitleView(){
            return (
                <Image source={{uri:'discover'}} style={{width:54,height:37}}/>
            )
        }
    }
    
    // 4.样式表 组件外观 尺寸,颜色
    var styles = StyleSheet.create({
        viewStyle:{
            flex:1,
            justifyContent:'center',
            alignItems:'center'
        }
    })
    

    模块当做一个对象导出知识点

    /**
     * @providesModule CommonGroupListViewHeader
     */
    
    import CommonGroupItem from  'CommonGroupItem'
    import CommonRowItem from  'CommonRowItem'
    import CommonSwitchRowItem from 'CommonSwitchRowItem'
    import CommonArrowRowItem from  'CommonArrowRowItem'
    import CommonGroupListView from 'CommonGroupListView'
    
    // 把当前模块当做一个对象导出
    module.exports = {
        CommonGroupItem,
        CommonRowItem,
        CommonSwitchRowItem,
        CommonArrowRowItem,
        CommonGroupListView
    }
    

    1.module.exports把里面所有内容当做一个整体,含有组头、该组所有cell类型,即CommonGroupListViewHeader拥有module.exports里面的五项内容。
    比如调用CommonGroupItem的方法(给该组所有视图包括头部,尾部,cell赋值):
    var group1 = new CommonGroupListViewHeader.CommonGroupItem(allRowData,sectionData.height);
    2.module.exports里面每一个都要声明,比如CommonGroupItem.js有代码如下
    module.exports = CommonGroupItem; // 在JS中,每个文件相当于一个模块

    ListView知识点

    • 使用

    1.创建数据源,但还没有给它传递数据
    使用state保存数据源,因为数据源的数据改变的时候,需要刷新界面
    方法:
    ListView.DataSource:获取ListViewDataSource构造方法
    ListViewDataSource构造方法:决定ListView怎么去处理数据,需要传入一个对象
    getRowData(dataBlob, sectionID, rowID): 怎么获取行数据
    getSectionHeaderData(dataBlob, sectionID): 怎么获取每一组头部数据
    rowHasChanged(prevRowData, nextRowData): 决定什么情况行数据才发生改变,当行数据发生改变,就会绘制下一行cell
    sectionHeaderHasChanged(prevSectionData, nextSectionData): 决定什么情况头部数据才发生改变,当行数据发生改变,就会绘制下一行cell
    初始化ListViewDataSource的时候,如果不需要修改提取数据的方式,只需要实现rowHasChanged,告诉什么时候刷新下一行数据

    constructor(props) {
      super(props);
      var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
     }
    

    2.给数据源设置数据

    constructor(props) {
      super(props);
    // 初始化数据源
            var ds = new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!=r2,
                sectionHeaderHasChanged:(s1,s2)=> s1 != s2
            });
    
    // 设置数据 分组使用:cloneWithRowsAndSections 不分组使用:cloneWithRows
            ds = ds.cloneWithRowsAndSections(sectionData)
            this.state = {
                ds:ds
            }
    

    分组样式:只要数据结构如下类型,就会产生分组样式

    { sectionID_1: { rowID_1: rowData1, ... }, ... }
    或者:
    { sectionID_1: [ rowData1, rowData2, ... ], ... }
    或者:
    [ [ rowData1, rowData2, ... ], ... ]
    
    • 如例子:自定义分组ListView:CommonGroupListViewHeader.js
    /**
     * @providesModule CommonGroupListView
     */
    import React, {Component,PropTypes} from 'react'
    
    import
    {
        AppRegistry,
        StyleSheet,
        Text,
        View,
        ListView
    
    }from 'react-native'
    
    import CommonRowCell from 'CommonRowCell'
    
    export default class CommonGroupListView extends Component {
    
        static propTypes = {
            groups:PropTypes.array,
            groupListViewStyle:PropTypes.oneOfType([PropTypes.number,PropTypes.object]),
            imageStyle:PropTypes.oneOfType([PropTypes.number,PropTypes.object]),
            titleStyle:PropTypes.oneOfType([PropTypes.number,PropTypes.object]),
            subTitleStyle:PropTypes.oneOfType([PropTypes.number,PropTypes.object]),
            navigator:PropTypes.object,
    
            renderHeader:PropTypes.func,
            renderFooter:PropTypes.func,
        }
    
        constructor(props){
            super(props);
    
            // 初始化数据源
            var ds = new ListView.DataSource({
                rowHasChanged:(r1,r2)=>r1!=r2,
                sectionHeaderHasChanged:(s1,s2)=> s1 != s2
            });
    
            // 处理组模型数组
            var groups = this.props.groups;
    
            var sectionData = [];
    
            groups.forEach((groupItem,i)=>{
                sectionData.push(groupItem.rowsData);
            })
    
            // 设置数据 分组使用:cloneWithRowsAndSections 不分组使用:cloneWithRows
            ds = ds.cloneWithRowsAndSections(sectionData)
            this.state = {
                ds:ds
            }
        }
    
        render(){
    
            return (
                <ListView dataSource={this.state.ds}
                          renderRow={this._renderRow.bind(this)}
                          renderSectionHeader={this._renderSectionHeader.bind(this)}
                          style={this.props.groupListViewStyle}
                          renderHeader={this.props.renderHeader}
                          renderFooter={this.props.renderFooter}
                />
            )
    
        }
    
        _renderRow(rowData,sectioniD,rowID){
    
            return (
                    rowData.customData?<rowData.customCellType rowData={rowData} {...this.props}/>:<CommonRowCell rowData={rowData} {...this.props}/>
                )
        }
        _renderSectionHeader(sectionData, sectionID){
            // 获取组模型就好了
    
            var groupItem = this.props.groups[sectionID];
    
            return (
                <View style={{height:groupItem.sectionHeight}}></View>
            )
        }
    }
    
    var styles = StyleSheet.create({
        viewStyle:{
            flex:1,
            justifyContent:'center',
            alignItems:'center'
        }
    })
    
    • 其他
      头部,尾部
     _renderHeader() {
            return (
                <View>
                    <Text>头部视图</Text>
                </View>
            )
        }
    
    _renderFooter() {
            return (
                <View>
                    <Text>尾部视图</Text>
                </View>
            )
        }
    
    

    点击高亮

    _renderRow(rowData, sectionID, rowID, highlightRow) {
    
            return (
                <TouchableOpacity onPress={()=>{
                    highlightRow(sectionID,rowID)
                }}>
                    <View>
                        <Text>{rowData}</Text>
                    </View>
                </TouchableOpacity>
    
            );
        }
    

    分割线

    _renderSeparator(sectionID, rowID, adjacentRowHighlighted)  {
            return (
                <View style={{height:1,backgroundColor:'black'}}></View>
            )
        }
    

    导航栏跳转知识点

    • 导航栏跳转以及数据传递 Discover.js中
            rowDatas.forEach((rowData,i)=>{
                var item = new CommonGroupListViewHeader.CommonRowItem();
                item.customData = rowData;
                item.customCellType = DiscoverVideoCell;
                item.route = { //变量赋值传递数据用于跳转
                    component:VideoView,  // 定义变量说明跳转的视图
                    videoUri:rowData.video // 定义变量说明参数数据  video是json字段
                }
                allRowData.push(item);
            });
    

    CommonRowCell.js中拥有rowData每一行的数据,拿到rowData中的route就可以push

    if(this.props.rowData.route){  // 如果this.props.rowData.route有值,即外界有传递数据
                 var route = this.props.rowData.route;
                 route.navigator = this.props.navigator;
                 this.props.navigator.push(route);
     }
    

    VideoView.js

    取数据:this.props.videoUri

    http://reactnative.cn/docs/0.49/navigation.html#content

    所以,相当于

    this.props.navigator.push({
          component:VideoView,  
           videoUri:rowData.video
      });
    
    • 附上CommonRowCell.js
      样式:
    /**
     * @providesModule CommonRowCell
     */
    import React, {Component,PropTypes} from 'react'
    
    // 2.导入常用组件,注册组件,样式组件,View组件,Text组件
    import
    {
        AppRegistry,
        StyleSheet,
        Text,
        View,
        TouchableOpacity,
        Image,
        PixelRatio,
        Switch
    
    }from 'react-native'
    
    import Common from 'Common'
    
    export default class CommonRowCell extends Component {
    
        static propTypes = {
            rowData:PropTypes.object
        }
    
        constructor(props){
            super(props);
    
            this.state = {
                isOn:false
            }
    
            // 判断下当前是否是开关,如果是开关,就不能设置子标题
            var className = this.props.rowData.constructor.name;
    
            if (className == 'CommonSwitchRowItem') {
    
                // 判断子标题
                if (this.props.rowData.subTitle){
                    throw '开关模型,不允许设置子标题';
                }
    
            }
        }
    
        render(){
            return (
                <TouchableOpacity style={styles.cellStyle}
                                  onPress={()=>{
    
                                      if(this.props.rowData.clickCell){
                                          this.props.rowData.clickCell();
                                      }
    
                                      if(this.props.rowData.route){
                                          var route = this.props.rowData.route;
                                          route.navigator = this.props.navigator;
                                          this.props.navigator.push(route);
                                      }
                                  }}
                                  disabled={this.props.rowData.disabled}
                >
                    {/*图片*/}
                    {this.props.rowData.image?<Image source={{uri:this.props.rowData.image}} style={[styles.imageStyle,this.props.imageStyle]}/>:null}
                    {/*标题*/}
                    <Text style={[styles.titleStyle,this.props.titleStyle]}>{this.props.rowData.title}</Text>
                    {/*子标题 switch*/}
                    <Text style={[styles.subTitleStyle,this.props.subTitleStyle]}>{this.props.rowData.subTitle}</Text>
                    {this._renderAccessoryView()}
                </TouchableOpacity>
            )
        }
    
        // 渲染右边辅助视图
        _renderAccessoryView(){
            // 获取当前对象的构造方法 => 类名
            var className = this.props.rowData.constructor.name;
            // 判断当前模型属于哪个类
            if (className == 'CommonArrowRowItem'){ {/*箭头*/}
                return (
                    <Image source={{uri:'icon_shike_arrow'}} style={styles.arrowStyle}/>
                )
            } else if (className == 'CommonSwitchRowItem'){ {/*开关*/}
                return (
                    <Switch style={styles.switchStyle}
                            onValueChange={(newValue)=>{
                                this.setState({
                                    isOn:newValue
                                })
                            }}
                            value={this.state.isOn}
                    />
                )
            }
    
            {/*什么都不显示*/}
        }
    }
    
    var styles = StyleSheet.create({
        cellStyle:{
            flexDirection:'row',
            alignItems:'center',
            width:Common.screenW,
            height:44,
            borderBottomColor:'#e5e5e5',
            borderBottomWidth:1 / PixelRatio.get(),
            backgroundColor:'white'
        },
        imageStyle:{
            width:25,
            height:25,
            marginLeft:5
        },
        arrowStyle:{
            width:7,
            height:12,
            position:'absolute',
            right:5
        },
        titleStyle:{
            marginLeft:5
        },
        subTitleStyle:{
            marginLeft:5
        },
        switchStyle:{
            position:'absolute',
            right:5
        },
    })
    

    相关文章

      网友评论

          本文标题:RN学习-ListView列表

          本文链接:https://www.haomeiwen.com/subject/tcoouxtx.html