搜索
您的当前位置:首页正文

React-Native左右联动List的示例代码

2020-11-27 来源:赴品旅游

一:左右联动List,在工作中很常见。

今天分享一个同事写的例子,本人只做了简单修改。

注意:本例子必须修改源码,参考本文第三条。

二:Coding

ParcelPage.js:

import React, { Component } from 'react';
import {
 AppRegistry,
 StyleSheet,
 Text,
 View,
 FlatList,
 SectionList,
 Dimensions,
 TouchableOpacity,
 Image,
} from 'react-native';

import ParcelData from './ParcelData.json'

var { width, height } = Dimensions.get('window');

let Headers = [];


export default class ParcelPage extends Component {

 static navigationOptions = ({ navigation }) => ({
 headerTitle : '联动List',
 });

 componentDidMount() {
 ParcelData.map((item, i) => {
 Headers.push(item.section);
 });
 };

 componentWillUnmount() {
 Headers = [];
 };

 renderLRow = (item) => {
 return (
 <TouchableOpacity style={[ styles.lItem, {backgroundColor: item.index == this.state.cell ? 'white' : null} ]}
 onPress={()=>this.cellAction(item)}>
 <Text style={styles.lText}>{ item.item.section }</Text>
 </TouchableOpacity>
 )
 };

 cellAction = (item) => {
 if (item.index <= ParcelData.length) {
 this.setState({
 cell : item.index
 });
 if (item.index > 0) {
 var count = 0;
 for (var i = 0;
 i < item.index;
 i++) {
 count += ParcelData[ i ].data.length + 1
 }
 this.refs.sectionList.scrollToIndex({ animated : false, index : count })
 } else {
 this.refs.sectionList.scrollToIndex({ animated : false, index : 0 });
 }

 }

 };

 itemChange = (info) => {
 let section = info.viewableItems[ 0 ].section.section;
 if (section) {
 let index = Headers.indexOf(section);
 if (index < 0) {
 index = 0;
 }
 this.setState({ cell : index });
 }
 };

 state = {
 cell : 0
 };

 renderRRow = (item) => {
 return (
 <View style={ styles.rItem }>
 <Image style={ styles.icon } source={{ uri : item.item.img }}/>
 <View style={ styles.rItemDetail }>
 <Text style={ styles.foodName }>{ item.item.name }</Text>
 <View style={ styles.saleFavorite }>
 <Text style={ styles.saleFavoriteText }>{ item.item.sale }</Text>
 <Text style={ [styles.saleFavoriteText,{ marginLeft:15 }]}>{ item.item.favorite }</Text>
 </View>
 <Text style={ styles.moneyText }>¥{ item.item.money }</Text>
 </View>
 </View>
 )
 };

 sectionComp = (section) => {
 return (
 <View style={{height:30,backgroundColor:'#DEDEDE',justifyContent:'center',alignItems:'center'}}>
 <Text >{section.section.section}</Text>
 </View>
 )
 };

 separator = () => {
 return (
 <View style={{height:1,backgroundColor:'gray'}}/>
 )
 };

 render() {
 return (
 <View style={ styles.container }>
 <FlatList
 ref='FlatList'
 style={ styles.leftList }
 data={ ParcelData }
 renderItem={(item) => this.renderLRow(item)}
 ItemSeparatorComponent={ () => this.separator() }
 keyExtractor={ (item) => item.section }
 />
 <SectionList
 ref='sectionList'
 style={ styles.rightList }
 renderSectionHeader={ (section) => this.sectionComp(section) }
 renderItem={ (item) => this.renderRRow(item) }
 sections={ ParcelData }
 keyExtractor={ (item) => item.name }
 onViewableItemsChanged={ (info) => this.itemChange(info) }
 />
 </View>
 );
 }
}

const styles = StyleSheet.create({
 container : {
 flexDirection : 'row'
 },
 leftList : {
 width : 1 * width / 4,
 backgroundColor : '#E9E9EF'
 },
 lItem : {
 minHeight : 44,
 justifyContent : 'center',
 },
 lText : {
 marginLeft : 10,
 marginRight : 10,
 fontSize : 16,
 },
 rightList : {
 width : 3 * width / 4
 },
 rItem : {
 flexDirection : 'row'
 },
 rItemDetail : {
 flex : 1,
 marginTop : 10,
 marginLeft : 5
 },
 icon : {
 height : 60,
 width : 60,
 marginTop : 10,
 marginBottom : 10,
 marginLeft : 8,
 borderWidth : 1,
 borderColor : '#999999'
 },
 foodName : {
 fontSize : 18,
 },
 saleFavorite : {
 flexDirection : 'row',
 marginTop : 5,
 marginBottom : 5,
 },
 saleFavoriteText : {
 fontSize : 13,
 },
 moneyText : {
 color : 'orange'
 },
});

ParcelData.js

[
 {
 "section" : "热销",
 "data" : [
 {
 "name" : "蟹黄汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "20",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "小馄饨",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "蟹黄汤包+牛杂粉丝汤套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "35",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "鸭血粉丝汤",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "15",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "介绍我们",
 "data" : [
 {
 "name" : "慎用差评!任何问题联系我们就可解决哦",
 "sale" : "月售1",
 "favorite" : "赞0",
 "money" : "0",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 }
 ]
 },
 {
 "section" : "折扣套餐",
 "data" : [
 {
 "name" : "特色蟹黄汤包+鸭血粉丝汤+果汁套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "50",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "蟹黄汤包+牛杂粉丝汤套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "35",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "蟹黄汤包+南瓜粥+果汁套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "金牌蟹黄汤包+紫米粥+柠檬果汁套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "台式卤肉饭+南瓜粥套餐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "纯手工汤宝",
 "data" : [
 {
 "name" : "金牌蟹黄汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "蟹庭丰特色蟹黄汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "蟹黄汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "干贝汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "鲍鱼汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "全家福汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "虾仁汤包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "汤、粥类",
 "data" : [
 {
 "name" : "紫米粥",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "金丝南瓜粥",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "小米粥",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "白粥",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "面食类",
 "data" : [
 {
 "name" : "鸡汤面",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "红烧小排面",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "红烧牛肉面",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "调味小菜",
 "data" : [
 {
 "name" : "肉松",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "辣椒包",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "泡菜",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "酱黄瓜",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "萝卜干",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 },
 {
 "section" : "饮料",
 "data" : [
 {
 "name" : "可乐",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/__39230311__3449301.jpg"
 },
 {
 "name" : "雪碧",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p1.meituan.net/deal/849d8b59a2d9cc5864d65784dfd6fdc6105232.jpg"
 },
 {
 "name" : "王老吉",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 },
 {
 "name" : "橙汁",
 "sale" : "月售875",
 "favorite" : "赞31",
 "money" : "10",
 "img":"http://p0.meituan.net/deal/ed3025663342b126eaae24764704b017136487.jpg"
 }
 ]
 }
]

三:修改源码

1-:SectionList

node_modules/react-native/Libraries/Lists/SectionList.js,代码格式化后大概在187行的位置,修改如下

 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);
 }
}

2-:VirtualizedSectionList

路径在node_modules/react-native/Libraries/Lists/VirtualizedSectionList.js,大概253行处修改如下:

render() {
 return <VirtualizedList
 ref={this._captureRef}
 {...this.state.childProps} />;
 }

 _captureRef = (ref) => {
 this._listRef = ref;
 };

 scrollToIndex = (params: { animated?: ?boolean, index: number, viewPosition?: number }) => {
 this._listRef.scrollToIndex(params);
 }


四:

1-:代码github地址:https://github.com/erhutime/React-Navigation-All

2-:下载完成后,修改index.ios.js:入口文件如下:

import App from './jscode/doubleList/App'
AppRegistry.registerComponent('All', () => App);

五:效果图如下:

Top