react native ListView
发布在react native2015年12月14日view:7531
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

中文一般译作列表视图,就是一个带垂直滚动条功能的列表,可以说是ScrollView的封装。实际上,其源码也是这样干。它对滚动做了许多优化,因此性能比较直接用ScrollView高。网上许多Grid都是基它封装的。

ListView一个最重要的配置项是ListView.DataSource,目的是放入一个数组,然后由它控制怎么显示或退出某部分数组元素,而不是一下子全部显示出来(当然你没有处理,它会全部显示的)。

我们看一个简单的例子。官网的例子简直没法看。

style.css (一会儿用react-native-css模块转换style.js)

row {
  text-align: center;
  line-height: 30;
  font-size: 16;
  background-color:#51c9d2;
  margin-top: 2;
}

主程序如下:


/**
 * ListView 司徒正美
 */
'use strict';

var React = require('react-native');
var styles = require('./style')
var {
  AppRegistry,
  Text,
  ListView,
  View
} = React
var mockArray = Array(101).join("1").split("").map(function(el,index){
  return 'row '+ (index+1)
})
var AwesomeProject = React.createClass({
  getInitialState: function() {
  var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
  return {
    dataSource: ds.cloneWithRows(mockArray)
  };
},
  render: function() {

    return (
      <ListView
       dataSource={this.state.dataSource}
       renderRow={(rowData) => <Text>{rowData}</Text>}
      />
    );
  }
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

enter image description here

现在我们弄复杂一点,做一个类似表头固定的效果。列表的数据是一个二维数组,就像optgroup与option的关系 ,我们要高亮的optgroup元素,并且它会贴粘在最上放,直到下一个optgroup移上来时取替它。这时我们需要renderSectionHeader方法。

但有关数据,文档非常不详细,我找了许久终于整出来。大家认真看注释。注意,ListView如果被其他View包着,必须定义父元素是flexbox。



container {
    flex: 1;
}
list{
  background-color: #dff0d8;
}

header {
    height: 60;
    justify-content: center;
    align-items:center;
    background-color:#3F51B5;
    flex-direction: column;
    padding-top: 25;
}

headerText {
    font-weight:bold;
    font-size: 20;
    color: white;
}

section {
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding: 6;
    background-color: #2196F3;
}

sectionText {
  color: white;
  padding-horizontal: 8;
  font-size: 16;
}


row{
    padding-vertical: 20;
    padding-left: 16;
    border-color: white;
    border-bottom-color: #eoeoeo;
    border-width: 1;
}
rowText {
    color: #468847;
    fontSize: 16;
}

主程序如下:

/**
 * List的表头贴着效果 by 司徒正美
 */
'use strict';

var React = require('react-native');
var {
    AppRegistry,
    Text,
    View,
    ListView,
    } = React;
var styles = require("./style")
//要求原数组是一个对象数组,对象下面还有一个子数组,方便转换
var mockData = [
  {
    id:"aaa",
    sub: Array(11).fill(1).map((el, index) => {
      return "first " + index
    })
  },
  {
    id:"bbb",
    sub: Array(11).fill(1).map((el, index) => {
      return "second " + index
    })
  },
  {
    id:"ccc",
    sub: Array(11).fill(1).map((el, index) => {
      return "third " + index
    })
  },
  {
    id:"ddd",
    sub: Array(11).fill(1).map((el, index) => {
      return "fourth " + index
    })
  }
]


var List = React.createClass({

    getInitialState() {
      //转换为一个一维对象数组
        var convertToObject = (array) => {
          var dataBlob = {},
          sectionIDs = [],
          rowIDs = []
          sectionIDs = array.map((el, index) => {
              var sid = el.id
              dataBlob[sid] = el
              rowIDs[index] = el.sub.map((elem) => {
                  var key = el.id +":"+elem
                  dataBlob[key] = elem
                  return key
              })
              return sid
          })
          return {
            dataBlob: dataBlob,//一个对象
            sectionIDs: sectionIDs,// 一个一维数组 [string|number, string|number, string|number ...]
            rowIDs: rowIDs // 一个二维数组,[[string|number],[string|number],[string|number]...]
          }
      }

      var {
        dataBlob,
        sectionIDs,
        rowIDs,
      } = convertToObject(mockData)


      var getSectionData = (dataBlob, sectionID) => {
          return dataBlob[sectionID];
      }

      var getRowData = (dataBlob, sectionID, rowID) => {
          //console.log(dataBlob, sectionID, rowID)
          return dataBlob[rowID];
      }


      var source = new ListView.DataSource({//这是定义结构
          getSectionData          : getSectionData,
          getRowData              : getRowData,
          rowHasChanged           : (row1, row2) => row1 !== row2,
          sectionHeaderHasChanged : (s1, s2) => s1 !== s2
      }).cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs)//这是添加数据

      return {
            dataSource : source
       }
    },

    renderRow(rowData, sectionID, rowID) {

        return (
                <View style={styles.row}>
                    <Text style={styles.rowText}>{rowData}</Text>
                </View>
        );
    },


    renderSectionHeader(sectionData, sectionID) {
        return (
            <View style={styles.section}>
                <Text style={styles.sectionText}>{sectionData.id}</Text>
            </View>
        );
    },

    render() {
        return (
          <View style={styles.container}>
              <View style={styles.header}>
                  <Text style={styles.headerText}>ListView的section sticky效果</Text>
              </View>
              <ListView
                  dataSource = {this.state.dataSource}
                  style={styles.list}
                  renderRow  = {this.renderRow}
                  renderSectionHeader = {this.renderSectionHeader}
              />
          </View>
        )
    }

});

AppRegistry.registerComponent('AwesomeProject', () => List);

enter image description here

评论
发表评论
4年前
添加了一枚【评注】:这应该是 (rowData, index)吧
WRITTEN BY
司徒正美
穿梭于二次元与二进制间的魔法师( ̄(工) ̄) 凸ส้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้
TA的新浪微博
PUBLISHED IN
react native

用于放置react native的相关文章

我的收藏