ReactNative中SectionList实现条目GridView效果

来源:互联网 发布:英语课文朗读软件 编辑:程序博客网 时间:2024/06/14 18:20

本文纯原创,纯手打,请大神多多指教。转载请注明出处!
react-native版本:0.48; 开发环境win10+VScode; 目标平台:安卓(暂时没有适配苹果); 最后更新时间:2017.09.11;


在ReactNative,想做个Android中分组GridView的效果,搜索了半天没找到解决办法,于是自己瞎摸索出来了一套效果,目前就是用SectionList嵌套FlatList,但是这肯定不是最优的方法,还请大神指点

先看下效果图

1. 数据格式

    var data0={name:'外勤签到',img:Images.oaWQQD,onPress:()=>alert('跳转页面----外勤签到') }    var data1={name:'考勤打卡',img:Images.oaKQDK}    var data2={name:'审批',img:Images.oaSP}    var data3={name:'日志',img:Images.oaRZ}    OAData.push(data0)    OAData.push(data1)    OAData.push(data2)    var AllMenu2=[         {key:0,title:'办公',data:OAData},         {key:1,title:'营销',data:YXData},    ]

2.代码

源代码地址:https://github.com/MyPublicGitHub/Test.git

import React from 'react'import { StyleSheet, View, Image, Text, ImageBackground, TouchableOpacity, ToastAndroid, SectionList, FlatList ,RefreshControl} from 'react-native'import Images from '../images/ImageList'import Api from '../api/Api'import GV from '../utils/GlobalVariable'import * as Progress from 'react-native-progress';var AllMenu = [];var Dimensions = require('Dimensions');//获取屏幕的宽高 var ScreenWidth = Dimensions.get('window').width;var ScreenHeight = Dimensions.get('window').height;class WorksView extends React.Component {   constructor(props) {       super(props);       this.state = {           isLoading: false,       };   }  static navigationOptions = {      headerTitle: <Text style={{ alignSelf: 'center', fontSize: 16, color: 'black', }}>工作台</Text>,      headerLeft: null,      headerStyle: {          height: 40,      }  }  componentDidMount() {      this._getModuleDefault()  }  _getModuleDefault() {      console.log("令牌" + GV.ACCESS_TOKEN)      if (GV.ACCESS_TOKEN !== '') {          var url = 'http://api.test.zhu-ku.com/zhuku/ws/system/sysroleapp/selectUserRoleAll/' + GV.ACCESS_TOKEN;          var header = {              method: 'get',          }          this.setState({              isLoading: true          })          fetch(url, header)              .then((response) => {                  return response.json()              })              .then((responseJson) => {                  if (responseJson.statusCode == '0000') {                      //ToastAndroid.show('获取权限成功', ToastAndroid.SHORT);                      this._initItem(responseJson.returnData);                  } else {                      //alert(responseJson.statusDesc + 'response')                      ToastAndroid.show('获取权限失败:' + responseJson.statusDesc, ToastAndroid.SHORT);                  }                  this.setState({                      isLoading: false                  })              })              .catch((error) => {                  alert(error)                  this.setState({                      isLoading: false                  })              })          //ToastAndroid.show('132132', ToastAndroid.SHORT);      }  }  _renderItem = ({ info }) => null  _renderSectionHeader = ({ section }) =>      <View>          <Text style={styles.viewItemHeader}>{section.title}</Text>          <FlatList              data={section.data}              style={styles.flastList}              numColumns={4}              renderItem={({ item }) =>                  <TouchableOpacity onPress={item.onPress}>                      <View style={styles.viewRow}>                          <Image source={item.img} style={styles.imageItem} />                          <Text style={styles.textItem}>{item.name}</Text>                      </View>                  </TouchableOpacity>              }          />      </View>  render() {      return (          this.state.isLoading ?              <View style={styles.load}>                  <Progress.CircleSnail style={{ margin: 10, alignSelf: 'center' }} color={['red', 'green', 'blue', 'black', 'yellow']} size={30} />                  <Text>正在加载...</Text>              </View>              :              <SectionList                  style={styles.background}                  renderSectionHeader={this._renderSectionHeader}                  renderItem={({ info }) => null}                  sections={AllMenu}                  //refreshing={this.state.isLoading}              />      )  }  _initItem(returnData) {      var OAData = []      var YXData = []      var CGData = []      var TJData = []      //OA模块数据是固定的      var data0 = { name: '外勤签到', img: Images.oaWQQD, onPress: () => alert('外勤签到') }      var data1 = { name: '考勤打卡', img: Images.oaKQDK }      var data2 = { name: '审批', img: Images.oaSP }      var data3 = { name: '日志', img: Images.oaRZ }      var data4 = { name: '任务', img: Images.oaRW }      var data5 = { name: '公告', img: Images.oaGG }      var data6 = { name: '证书', img: Images.oaZS }      var data7 = { name: '印章', img: Images.oaYZ }      var data8 = { name: '资产', img: Images.oaZC }      var data9 = { name: '车辆', img: Images.oaCL }      //把数据添加到办公子模块      OAData.push(data0)      OAData.push(data1)      OAData.push(data2)      OAData.push(data3)      OAData.push(data4)      OAData.push(data5)      OAData.push(data6)      OAData.push(data7)      OAData.push(data8)      OAData.push(data9)      //循环找出拥有权限的模块      for (var index = 0; index < returnData.length; index++) {          var element = returnData[index];          var menuId = element.menuId;          if (menuId == 16) {              YXData.push({ name: '项目信息', img: Images.yxXMXY })          }          if (menuId == 17) {              YXData.push({ name: '营销任务', img: Images.yxYXRW })          }          if (menuId == 18) {              YXData.push({ name: '同行分析', img: Images.yxTHFX })          }          if (menuId == 19) {              YXData.push({ name: '投标管理', img: Images.yxTBGL })          }          if (menuId == 20) {              YXData.push({ name: '业绩PK', img: Images.yxYJPK })          }          if (menuId == 21) {              YXData.push({ name: '客户看板', img: Images.yxKHKB })          }          //采购          if (menuId == 29) {              CGData.push({ name: '供应商', img: Images.cgGYS })          }          if (menuId == 30) {              CGData.push({ name: '物资采购', img: Images.cgWZCG })          }          if (menuId == 31) {              CGData.push({ name: '供应商评价', img: Images.cgGYSPJ })          }          if (menuId == 32) {              CGData.push({                  name: '供应商往来', img: Images.cgGYSWL, onPress: () => alert('供应商往来')              })          }          //统计          if (menuId == 8) {              TJData.push({ name: '管理统计', img: Images.tjGLTJ })              TJData.push({ name: '项目统计', img: Images.tjXMTJ })          }      }      var OAMenu = { key: 0, title: '办公', data: OAData }//把办公子模块添加到办公模块      var YXMenu = { key: 1, title: '营销', data: YXData }//把营销子模块添加到营销模块      var CGMenu = { key: 2, title: '采购', data: CGData }//把采购子模块添加到采购模块      var TJMenu = { key: 3, title: '统计', data: TJData }//把统计子模块添加到统计模块      AllMenu.push(OAMenu);//讲办公添加到模块集合      AllMenu.push(YXMenu);//讲营销添加到模块集合      AllMenu.push(CGMenu);//讲采购添加到模块集合      AllMenu.push(TJMenu);//讲统计添加到模块集合  } }  viewItemHeader: {      flex: 1,      backgroundColor: '#eeeeee',      alignItems: 'center',      paddingLeft: 20,      paddingTop: 5,      paddingBottom: 5,  },  viewRow: {      // flexDirection: 'row',//设置横向布局       justifyContent: 'center',      alignItems: 'center',      width: ScreenWidth / 4,      padding: 10,  },  imageItem: {      height: 40,      width: 40,  },  textItem: {      textAlignVertical: 'center',      color: '#5C5C5C',      fontSize: 12,  },  flastList: {  }, }) export default WorksView

3.总结

简书还是不智能,复制的代码 全部去掉看空格,我已经优化了一下,可能有的地方报错,需要补空格。
我在代码中没有用到SectionList中的keyExtractor属性,可能有些地方会报黄色警告,建议大家把文中的title字段作为key。
关于SectionList的属性请到ReactNative中文网 了解

4.遇到的坑

4.1 如果把FlatList写到renderIten方法中会出现这样的情况

我猜测,这种情况是因为数据格式不对导致的,renderItem方法的参数是(info: {item: Item, index: number}) => ?所以参数全部都是数组中的对象信息(本文中是:{name:’营销任务’,img:Images.yxYXRW})但是,FlatList需要的数据格式是整个条目的数组
4.2 如果直接在renderItem中返回子条目
如果按照常规的逻辑,我们大概会这样写,写出来的效果比较适合做通讯录等,每个item占用一行。而不能把item 进行Z型排列;这是系统默认的效果,我在这个基础上摸索了半天 没处理好,还请大神指点

效果是这样的

阅读全文
0 0
原创粉丝点击