React-Native新列表元件FlatList和SectionList學習 | | 聯動列表實現
React-Native在0.43推出了兩款新的列表元件:FlatList(高效能的簡單列表元件)和SectionList(高效能的分組列表元件).
http://www.cnblogs.com/shaoting/p/7069312.html
從官方上它們都支援常用的以下功能:
- 完全跨平臺。
- 支援水平佈局模式。
- 行元件顯示或隱藏時可配置回撥事件。
- 支援單獨的頭部元件。
- 支援單獨的尾部元件。
- 支援自定義行間分隔線。
- 支援下拉重新整理。
- 支援上拉載入。
其中,SectionList適合分組/類/區,但是在0.43版本中,如果希望section的頭部能夠吸頂懸浮,請暫時先使用老版的
它們都是基於<VirtualizedList>
keyExtractor
函式來動態繫結資料來源中的id等其他不唯一的資料。如果不繫結會報一個警告:
接下里使用這兩個元件寫一個demo:列表元件的聯動(ps:其實個人感覺使用ListView實現更加方便.也更易擴充套件)
資料來源我們採用本地資料:
{ "food_spu_tags":[ { "title":"1", "data":[ { "name":"一 nghnh", "key":"1" }, { "name":"一 tyui22uyt", "key":"2" }, { "name":"一 3fdsfdga", "key":"3" } ] }, {"title":"2", "data":[ { "name":"二 fsd", "key":"4" }, { "name":"二 gfdh", "key":"5" }, { "name":"二 ghdsfd", "key":"6" }, { "name":"二 hkjhg", "key":"7" }, { "name":"二 oiuytre", "key":"8" }, { "name":"二 phfd", "key":"9" } ] }, { "title":"3", "data":[ { "name":"三 pknbv", "key":"10" }, { "name":"三 qazxsef", "key":"11" }, { "name":"三 plmnbgf", "key":"12" }, { "name":"三 ggggg", "key":"13" }, { "name":"三 gfd", "key":"14" }, { "name":"三 fgh", "key":"15" }, { "name":"三 hhf", "key":"16" }, { "name":"三 jff", "key":"17" }, { "name":"三 sfgd", "key":"18" }, { "name":"三 dffhsd", "key":"19" }, { "name":"三 ghd", "key":"20" }, { "name":"三 ghsg", "key":"21" } ] }, { "title":"4", "data":[ { "name":"四 ghs", "key":"22" }, { "name":"四 hth", "key":"23" } ] }, { "title":"5", "data":[ { "name":"五 teh", "key":"24" }, { "name":"五 thtr", "key":"25" }, { "name":"五 thereth", "key":"26" }, { "name":"五 yefdgs", "key":"27" }, { "name":"五 htweh", "key":"28" }, { "name":"五 thrhwt", "key":"29" }, { "name":"五 geheht", "key":"30" }, { "name":"五 thwtw", "key":"31" } ] }, { "title":"6", "data":[ { "name":"六 thsfsg", "key":"32" }, { "name":"六 thwfs", "key":"33" }, { "name":"六 htsfd", "key":"34" } ] }, { "title":"7", "data":[ { "name":"七 hgshfd", "key":"35" } ] }, { "title":"8", "data":[ { "name":"八 rgdsgsfd", "key":"36" }, { "name":"八 grht", "key":"37" }, { "name":"八 htrfss", "key":"38" }, { "name":"八 thsgfd", "key":"39" }, { "name":"八 hthe", "key":"40" }, { "name":"八 trgtsf", "key":"41" }, { "name":"八 f45f", "key":"42" }, { "name":"八 4qtq", "key":"43" }, { "name":"八 43f", "key":"44" }, { "name":"八 43ff", "key":"45" }, { "name":"八 45gwrsfd", "key":"46" } ] }, { "title":"9", "data":[ { "name":"九 43qgf", "key":"47" }, { "name":"九 ref3", "key":"48" }, { "name":"九 54sf", "key":"49" } ] }, { "title":"10", "data":[ { "name":"十 43refsd", "key":"50" }, { "name":"十 43refzd", "key":"51" }, { "name":"十 4q3gfd", "key":"52" }, { "name":"十 wgf", "key":"53" }, { "name":"十 4q3fs", "key":"54" } ] }, { "title":"11", "data":[ { "name":"十一 wrf", "key":"55" }, { "name":"十一 5ersf", "key":"56" }, { "name":"十一 43fs", "key":"57" }, { "name":"十一 43fs", "key":"58" }, { "name":"十一 5gs", "key":"59" }, { "name":"十一 w5gfsd", "key":"60" }, { "name":"十一 4qrgfs", "key":"61" } ] }, { "title":"12", "data":[ { "name":"十二 4wgfsd", "key":"62" }, { "name":"十二 w5gfsd", "key":"63" }, { "name":"十二 4qgfsgf", "key":"64" }, { "name":"十二 3qgsf", "key":"65" } ] } ] }
1.新建個主類放置左右兩個列表元件(左邊的FlatList右邊的SectionList)
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; import LeftFlatList from './leftFlatList' import RightSectionList from './RightSectionList' import linkageData from './linkage.json' export default class Main extends Component { render() { return ( <View style={{flexDirection:'row'}}> <LeftFlatList data = {linkageData}/> <RightSectionList data = {linkageData}/> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, });
2.左邊的FlatList,key採用keyExtractor函式繫結,就是資料來源中title.
/** * Created by shaotingzhou on 2017/6/22. */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, Image, TouchableOpacity, Platform, Dimensions, RefreshControl, FlatList, ActivityIndicator, DeviceEventEmitter, ScrollView } from 'react-native'; var {width,height} = Dimensions.get('window'); var dataAry = [] export default class LeftFlatList extends Component{ // 構造 constructor(props) { super(props); dataAry = this.props.data.food_spu_tags this.state = { dataAry: dataAry, cell:0 //預設選中第一行 }; } render() { return ( <FlatList ref='FlatList' style={{width:80}} data = {this.state.dataAry} //資料來源 renderItem = {(item) => this.renderRow(item)} //每一行render ItemSeparatorComponent = {()=>{return(<View style={{height:1,backgroundColor:'cyan'}}/>)}} //分隔線 keyExtractor={this.keyExtractor} //使用json中的title動態繫結key /> ); } //使用json中的title動態繫結key keyExtractor(item: Object, index: number) { return item.title } //每一行render renderRow =(item) =>{ return( <TouchableOpacity onPress={()=>this.cellAction(item)}> <View style={{height:60,flexDirection:'row',alignItems:'center'}}> <View style={{height:50,width:5,backgroundColor: item.index == this.state.cell ? 'red' : 'rgba(0,0,0,0)'}}/> <Text style={{marginLeft:20}}>{item.item.title}</Text> </View> </TouchableOpacity> ) } //點選某行 cellAction =(item)=>{ // alert(item.index) if(item.index < this.state.dataAry.length - 1){ this.setState({ cell:item.index }) DeviceEventEmitter.emit('left',item.index); //發監聽 } } componentWillUnmount(){ // 移除監聽 this.listener.remove(); } componentWillMount() { this.listener = DeviceEventEmitter.addListener('right',(e)=>{ this.refs.FlatList.scrollToIndex({animated: true, index: e-1}) this.setState({ cell:e-1 }) }); } }; var styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, } });
3.右邊的SectionList,key採用資料來源中id來繫結.
/** * Created by shaotingzhou on 2017/6/22. */ import React, {Component} from 'react'; import { StyleSheet, View, Text, SectionList, Dimensions, DeviceEventEmitter, ScrollView } from 'react-native'; var {width,height} = Dimensions.get('window'); var sectionData = [] export default class RightSectionList extends Component { // 構造 constructor(props) { super(props); sectionData = this.props.data.food_spu_tags this.state = { sectionData:sectionData }; } //行 renderItem = (item) => { return ( <View style={{height:60,justifyContent:'center',marginLeft:15}}> <Text>{item.item.name}</Text> </View> ) } //頭 sectionComp = (section) => { return ( <View style={{height:30,backgroundColor:'#DEDEDE',justifyContent:'center',alignItems:'center'}}> <Text >{section.section.title}</Text> </View> ) } render() { return ( <SectionList ref='sectionList' style={{width:width-80}} renderSectionHeader={(section)=>this.sectionComp(section)} //頭 renderItem={(item)=>this.renderItem(item)} //行 ItemSeparatorComponent = {()=>{return(<View style={{height:1,backgroundColor:'black'}}/>)}}//分隔線 sections={this.state.sectionData} //資料 onViewableItemsChanged = {(info)=>this.itemChange(info)} //滑動時呼叫 /> ); } componentDidMount() { //收到監聽 this.listener = DeviceEventEmitter.addListener('left',(e)=>{ // console.log(e + 1) // 左邊點選了第幾行 // console.log(sectionData) // 資料來源 // console.log(sectionData[e]) // console.log(sectionData[e].data.length) // SectionList實現scrollToIndex需要修改VirtualizedSectionList和SectionList原始碼 if(e > 0){ //計算出前面有幾行 var count = 0 for(var i = 0; i < e; i++){ count += sectionData[i].data.length +1 } this.refs.sectionList.scrollToIndex({animated: true, index: count}) }else { this.refs.sectionList.scrollToIndex({animated: true, index: 0}) //如果左邊點選第一行,右邊則回到第一行 } }); } componentWillUnmount(){ // 移除監聽 this.listener.remove(); } itemChange = (info)=>{ let title = info.viewableItems[0].item.title var reg = new RegExp("^[0-9]*$"); if (reg.test(title)) { DeviceEventEmitter.emit('right',title); //發監聽 } } }
其中,使用事件監聽來實現點選和滑動的監聽.
我們使用scrollToIndex來移動.但是呢,FlatList對VirtualizedList封裝的時候有新增這個方法,而SectionList並沒有(why?).無奈自己修改下它的原始碼.
a.在node_modules/react-native/Libraries/Lists/SectionList.js 下修改 250-310行程式碼為
class SectionList<SectionT: SectionBase<any>> extends React.PureComponent<DefaultProps, Props<SectionT>, void> { props: Props<SectionT>; static defaultProps: DefaultProps = defaultProps; render() { const List = this.props.legacyImplementation ? MetroListView : VirtualizedSectionList; return <List ref={this._captureRef} {...this.props} />; } _captureRef = (ref) => { this._listRef = ref; }; scrollToIndex = (params: { animated?: ?boolean, index: number, viewPosition?: number }) => { this._listRef.scrollToIndex(params); } }
b.在node_modules/react-native/Libraries/Lists/VirtualizedSectionList.js 下的335下面增加
scrollToIndex = (params: { animated?: ?boolean, index: number, viewPosition?: number }) => { this._listRef.scrollToIndex(params); }
OK.修改完成後就可以實現點選左聯右了.
而右聯左,通過SectionList的onViewableItemsChanged屬性實現.
以後就是關於FlatList和SectionList的學習demo.
再說一遍,實現聯動元件最好使用ListView.因為現階段官方推出的FlatList和SectionList的方法較少,bug較多.
相關推薦
React-Native新列表元件FlatList和SectionList學習 | | 聯動列表實現
React-Native在0.43推出了兩款新的列表元件:FlatList(高效能的簡單列表元件)和SectionList(高效能的分組列表元件). http://www.cnblogs.com/shaoting/p/7069312.html 從官方上它們都支援常用
React Native 結合ScrollableTab、RefreshControl和FlatList實現新聞分類列表
正好剛開始學RN,熟悉一下控制元件和基本使用。 涉及的知識點: 1、fetch網路請求,get 拼接引數,解析json。 2、ScrollableTabView、ScrollableTabBar 分類佈局。 3、FlatList 資料列表。 4、Navigation
關於React-native裡Android原生模組和元件的寫法
原生模組就是把Android裡的API匯出來給JS呼叫,說簡單一點,就是讓自己寫的Java函式能夠在React Native的js程式碼裡呼叫。比如一些實現高效能的、多執行緒的程式碼,還有譬如圖片處理、資料庫、或者各種高階擴充套件等等。 舉個栗子: Toas
React Native的TextInput元件去掉下劃線和使用背景圖片
最近做RN,由於先做的是比較簡單的部分,所以沒碰到什麼難點。真正的難點還在後面,所以這周就記錄一下幾個小問題。也是比較常用的小問題了。 一、TextInput元件去掉下劃線和加上邊框 不得不說,RN自帶的TextInput輸入框是真的
《React-Native系列》元件封裝之Dialog(iOS和Android通用)
最近在專案中封裝了個Dialog元件,iOS和Android平臺上通用。 元件Dialog顯示時,從頁面頂部滑動到中間,點選確認或取消後,從頁面底部劃出頁面,需要注意動畫的實現。 原始碼如下: [javascript] view plain copy
React Native新元件之SwipeableFlatList
做過移動開發的同學都應該清楚,側滑刪除是移動開發中的一個常見功能。在官方沒提供側滑元件之前,要實現側滑效果需要使用第三方庫,如react-native-swipe-list-view。不過隨著React Native 0.50版本的釋出,系統新新增Swipeab
React-Native開發五 React Native 的Image元件
1 Image元件介紹 RN中Image元件主要用於載入圖片,可載入靜態圖片,網路圖片,以及原生圖片,本地檔案系統中圖片資源 官方參考https://facebook.github.io/react-native/docs/image#resizemode 2 Image元件功
React-Native開發四 React Native 的Touchable元件
1 Touchable元件簡介 Touchable元件是RN的按鈕元件,一共有四大類 TouchableWithoutFeedback:不帶任何反饋的可觸控元件 TouchableHighlight:在TouchableWithoutFeedback的基礎上添加了當按下時背景會變
React Native圖片快取元件
今天介紹一個React Native的圖片快取元件 react-native-rn-cacheimage ,純JS實現,所以相容性很好。 大家都知道,其實React Native 的 Image 元件在 iOS 端實現了快取,而android 端仍未實現,而且,就算實現了 iOS端 ,可能有些需求仍然比較難
React Native 筆記之元件
React Native的元件 什麼是React Native 元件? React Native 都有哪些元件? 建立元件的三種方式 [元件的生命週期](https://react.docschina.org/docs/react-compone
react native獲取螢幕的寬度和高度
var Dimensions = require('Dimensions'); var {width,height} = Dimensions.get("window");//第一種寫法 var width1 = Dimensions.get('window').width//第二種寫法 expor
React-Native 新版本無法Debug問題
最近無聊+手殘 升級rn到最新版本,然後出現了無法debug問題 具體症狀表現為 (index):94 Uncaught TypeError: Cannot set property 'volume' of null at Object.render ((index):94
react native的Navigator元件示例
import React, {Component} from 'react';import {ScrollView, StyleSheet, Text, View, PixelRatio} from 'react-native';import { Navigator } from 'react-native-
react-native react-navigation的用法 react native 導航路由元件react-navigation的使用
一、問題背景 react-navigation是react-native官方推薦的,基於Javascript的可擴充套件且使用簡單的導航,功能強大且完備 回顧一下,react-navigation包含以下功能來幫助我們建立導航器: StackN
react-native-vector-icons的安裝和使用
react-native-vector-icons是一個React Native 專案使用最廣泛的向量圖示圖示庫,使用簡單,內容豐富。 react-native-vector-icons官網 react-native-vector-icons圖示展示列表 使用react-native-vector-icon
React Native關於ScrollableTabView元件
最近工作中使用ScrollableTabView元件的問題,實現如下圖所示的效果: render方法中判斷state中狀態,進行佈局控制 render(){ if(this.state.error){ return(
React Native封裝原生元件釋出到npm
因為一個任務,要寫原生的獲取使用者手機資料夾,實現使用者自定義資料夾的功能,寫好了之後嘗試封裝成元件。1. 首先,有一個rn專案,用Adnroid Studio開啟 android -> app -> build.gradle如圖新建一個 Android Modu
react native開發中eslint配置和初始化
先簡單介紹一下mac系統環境下,eslint的配置。 首先開啟命令列工具,cd到專案根目錄下。 一次輸入命令並等待下載完成。 npm install eslint --save-dev npm ins
react native 倒計時控制元件
1.npm install //in package.json "dependencies": { "react_native_countdowntimer":"1.0.2" } //in your js code import CountDownTimer fr
React Native入門篇—react-native-splash-screen的安裝和配置
注意:未經允許不可私自轉載,違者必究 React Native官方文件:https://reactnative.cn/docs/getting-started/ react-native-splash-screen官方文件:https://github.com/crazycod