ReactNative中SectionList实现条目GridView效果

本文纯原创,纯手打,请大神多多指教。转载请注明出处!

react-native版本:0.48;  开发环境win10+VScode;  目标平台:安卓(暂时没有适配苹果);  最后更新时间:2017.09.11;


本文我又把编辑器改成MD重新发布了,建议浏览新地址 http://www.jianshu.com/p/a787d9af2401 

在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,TouchableOpacity,ToastAndroid,

    SectionList,FlatList

}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:工作台,

           headerLeft:null,

           headerStyle:{

                  height:40,

            } 

      }

componentDidMount() {

         this._getModuleDefault()

}

_getModuleDefault() {

          if(GV.ACCESS_TOKEN!=='') {

                 var url='网络地址';

                  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{

                            ToastAndroid.show('失败:'+responseJson.statusDesc,ToastAndroid.SHORT);

                     }

                      this.setState({

                             isLoading:false

                     })

                })

              .catch((error)=>{

                       alert(error)

                      this.setState({

                             isLoading:false

                      })

               })

     }

}

_renderItem=({info})=>null

_renderSectionHeader=({section})=>

      <View>

           

render() {

return(

this.state.isLoading?

正在加载...

:

style={styles.background}

renderSectionHeader={this._renderSectionHeader}

renderItem={this._renderItem}

sections={AllMenu}

/>

)

}

_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(varindex=0;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);//讲统计添加到模块集合

}

}

conststyles=StyleSheet.create({

load:{

flex:1,

justifyContent:'center',

alignItems:'center',

},

background:{

flex:1,

backgroundColor:'white'

},

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 defaultWorksView

3.总结

简书还是不智能,复制的代码 全部去掉看空格,我已经优化了一下,可能有的地方报错,需要补空格。

我在代码中没有用到SectionList中的keyExtractor属性,可能有些地方会报黄色警告,建议大家把文中的title字段作为key。

关于SectionList的属性请到ReactNative中文网 了解


条目层级

4.遇到的坑

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

把标题写到renderSectionHeader中把FlatList写到renderItem中


会发现sectinItem不显示了

我猜测,这种情况是因为数据格式不对导致的,renderItem方法的参数是(info: {item: Item, index: number}) => ?所以参数全部都是数组中的对象信息(本文中是:{name:'营销任务',img:Images.yxYXRW})但是,FlatList需要的数据格式是整个条目的数组

4.2 如果直接在renderItem中返回子条目

如果按照常规的逻辑,我们大概会这样写,写出来的效果比较适合做通讯录等,每个item占用一行。而不能把item 进行Z型排列;这是系统默认的效果,我在这个基础上摸索了半天 没处理好,还请大神指点


header返回text,item中返回图标

效果是这样的






最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容