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

一:左右联动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);

五:效果图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • react-native DatePicker日期选择组件的实现代码

    本教程的实现效果如下: 为了实现其淡入/淡出的覆盖效果, 还有取消按钮, 在此用了一个三方的组件, 大家可以先安装一下: 三方组件的地址:https://github.com/eyaleizenberg/react-native-custom-action-sheet(可以看看,也可以直接按我的步骤走) 1. 在terminal的该工程目录下运行: npm install react-native-custom-action-sheet --save 2. 然后运行: npm start 3.

  • React Native预设占位placeholder的使用

    当我们首次打开一个app的时候会请求接口获取数据,那么获取数据的这段时间展示什么给用户呢?国内很多app都是千篇一律的用一个菊花代替(俗称loading),或者更有心一点的做一个好看一点的loading,但是这样当拿到数据渲染页面的时候会很生硬的切换,总感觉很low. facebook首页列表是用一个接近真实布局的骨架动画来代替loading,这东西可以称之为skeleton screen或者placeholder,但是翻译过来真不知道该翻译成什么合适,这么做的好处就是在内容加载完成后可以做到流

  • React-Native使用Mobx实现购物车功能

    在工作中,购物车场景非常常见.本文实现基于React-Native和Mobx实现两种购物车例子. 其中,后期会加入动画等其他.本期先实现基础功能. 二:基于State实现购物车 1-:ShoppingCarPage.js export default class ShoppingCarPage extends Component { static navigationOptions = { headerTitle : '基于State购物车', }; constructor(props) { s

  • react.js 父子组件数据绑定实时通讯的示例代码

    react.js我自己还在摸索学习中,碰到父子组件数据绑定实时通讯的问题,研究了一下,分享给大家,也给自己留个笔记: import React,{Component} from 'react' import ReactDOM from 'react-dom' class ChildCounter extends Component{ render(){ return( <div style={{border:'1px solid red'}}> {this.props.count} </

  • 详解React Native监听Android回退按键与程序化退出应用

    详解React Native监听Android回退按键与程序化退出应用 前言 我们知道Android回退按键,会控制页面返回, 并且退出应用并非真正意义退出,仍在后台运行,所以在某些场景下需要监控android回退按键,那么在React Native中应该如何应用呢?我们具体来看看. BackAndroid 此模块用于监听硬件的back键操作. 看下具体代码: BackAndroid.addEventListener('hardwareBackPress', function() { if (!

  • React Native模块之Permissions权限申请的实例相机

    React Native模块之Permissions权限申请的实例详解 前言 对于移动开发,我们知道Android 6.0之后对于权限管理做了很大的升级,其类似于IOS的管理管理方式需要用手动授权是否允许使用当前权限, 在RN开发中同样存在这样一个模块. 处理方法 在RN中提供了一个PermissionsAndroid的模块, 可以访问Android M(也就是6.0)开始提供的权限模型.有一些权限写在AndroidManifest.xml就可以在安装时自动获得.但有一些"危险"的权限

  • React Native悬浮按钮组件的示例代码

    React Native悬浮按钮组件:react-native-action-button,纯JS组件,支持安卓和IOS双平台,支持设置子按钮,支持自定义位置和样式和图标. 效果图 安装方法 npm i react-native-action-button --save react-native link react-native-vector-icons 因为用到了react-native-vector-icons图标组件,需要做下link.如果你项目中已经使用了react-native-ve

  • React Native日期时间选择组件的示例代码

    React Native日期时间选择组件:react-native-datepicker,支持安卓和IOS双平台,支持单独选择日期.单独选择时间和选择日期和时间,支持自定义日期格式. 效果图 安装方法 npm install react-native-datepicker --save 示例代码 <Text style={styles.instructions}>time: {this.state.time}</Text> <DatePicker style={{width:

  • React Native 截屏组件的示例代码

    React Native 截屏组件:react-native-view-shot,可以截取当前屏幕或者按照当前页面的组件来选择截取,如当前页面有一个图片组件,一个View组件,可以选择截取图片组件或者View组件.支持iOS和安卓. 安装方法 npm install react-native-view-shot react-native link react-native-view-shot 使用示例 captureScreen() 截屏方法 截取当前屏幕,跟系统自带的截图一致,只会截取当前屏幕

  • react native与webview通信的示例代码

    WebView是ReactNative中的组件 , 它可以创建一个原生的WebView,可以用于访问一个网页. 有时候我们需要在RN与WebView之间进行通信,或者进行数据传递,或者发送消息通知.这时候就要用以下知识了. 一:WebView向RN端发送数据: 首先,我们构建一个webview: <WebView ref={'webview'} source={require('./index.html')} style={{width: 375, height: 220}} onMessage

  • 使用mint-ui实现省市区三级联动效果的示例代码

    引用插件:饿了么的mint-ui组件中的picker功能,具体API可参照官网说明:http://mint-ui.github.io/docs/#/zh-cn2/picker 背景:项目需要做一个省份-城市-地区的选择级联效果,我从gayhub上找了一下,决定使用mint-ui的组件,因为各个功能都很全而且设计跟我们的项目风格类似. 具体实现: 通过阅读官网的实例,大概就能知道这个组件的用法: 在vue中写入组件:<mt-picker :slots="slots" @change

  • React 实现拖拽功能的示例代码

    本文介绍了React 实现拖拽功能的示例代码,分享给大家,具体如下: 实现效果: 因为工作中会用到 JIRA 所以想实现一下相似的功能,顺便学习一下 H5 的拖拽.不支持拖拽改变顺序,感觉有点麻烦,而且没必要.感觉相关的博文好少的,大部分都是直接上代码,没有解释. 图片默认可以拖动,其他元素的拖动效果同图片.正常的 div 是不能被拖动的,鼠标点击选择后移动没有效果,需要加  draggable="true" 使得元素可以被拖动. 拖拽相关的几个事件,有被拖动元素的事件,也有拖动进入的

  • react native 仿微信聊天室实例代码

    一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN技术做了个自定义模态弹窗rnPop组件. 一.项目简述 基于react+react-native+react-navigation+react-redux+react-native-swiper+rnPop等技术开发的仿微信原生App界面聊天室--RN_ChatRoom,实现了原生app启动页.As

  • React实现登录表单的示例代码

    作为一个Vue用户,是时候扩展一下React了,从引入antd.配置less.router,终于实现了一个简单的登录表单. 代码如下: import React from 'react'; import { Input, Button, message } from "antd"; import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons'; impor

  • react实现浏览器自动刷新的示例代码

    在单页应用如此流行的今天,曾经令人惊叹的前端路由已经成为各大框架的基础标配,每个框架都提供了强大的路由功能,导致路由实现变的复杂.想要搞懂路由内部实现还是有些困难的,但是如果只想了解路由实现基本原理还是比较简单的.本文针对前端路由主流的实现方式 hash 和 history,提供了原生JS/React/Vue 共计六个版本供参考,每个版本的实现代码约 25~40 行左右(含空行). 什么是前端路由? 路由的概念来源于服务端,在服务端中路由描述的是 URL 与处理函数之间的映射关系. 在 Web

  • React实现核心Diff算法的示例代码

    目录 Diff算法的设计思路 Demo介绍 Diff算法实现 遍历前的准备工作 遍历after 遍历后的收尾工作 总结 Diff算法的设计思路 试想,Diff算法需要考虑多少种情况呢?大体分三种,分别是: 节点属性变化,比如: // 更新前 <ul> <li key="0" className="before">0</li> <li key="1">1</li> </ul>

随机推荐