【问题标题】:React Native: Capturing swiping event in SwipeListViewReact Native:在 SwipeListView 中捕获滑动事件
【发布时间】:2016-07-19 15:22:52
【问题描述】:

我正在寻找通过在SwipeListView 内向左或向右滑动SwipeRow 触发的事件。

我们的目标是拥有可以通过滑动轻松关闭的推送式通知。向向左(绿色)和向右(红色)滑动时,通知应逐渐改变颜色。在某个阈值 (60) 之后,应该触发最终事件,在这种情况下,accept(左)和 reject(右)并且通知应该消失。

目前这是通过我计划删除的按钮完成的。

来自SwipeListView docummentation,这可能有用:

onRowClose - 当滑动行动画关闭时调用的函数

onRowOpen - 当滑动行以动画方式打开时调用的函数

swipeRowStyle - 带有 SwipeRow 父包装视图样式的对象

leftOpenValue - 用于向左打开行的 TranslateX 数值(正数)

rightOpenValue - 用于向右打开行的 TranslateX 数值(负数)

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, ListView } from 'react-native';
import { SwipeListView, SwipeRow } from 'react-native-swipe-list-view'
var data = [ { id:0, notification: true, },{ id:1, notification: false, },{ id:2, notification: false, } ];

class SampleApp extends Component {

  render() {
    var ds = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
    return (
      <SwipeListView
        dataSource={ds.cloneWithRows(data)}
        onRowClose={() => {console.log("list.onRowClose")}}
        onRowOpen={() => {console.log("list.onRowClose")}}
        renderRow={ (data, secId, rowId, rowMap) => {
          return (
            <SwipeRow disableRightSwipe={false} disableLeftSwipe={false} leftOpenValue={60} rightOpenValue={-60} onRowClose={() => {console.log("row.onRowClose")}} onRowOpen={() => {console.log("row.onRowClose")}} swipeRowStyle={{}} leftOpenValue={60} rightOpenValue={-60}>
              <View style={{flexDirection:'row',justifyContent:'space-between',alignItems:'center', borderWidth:1}}>
                  <Text style={{flex: 1, paddingVertical:50,backgroundColor:'green', left:0, right:0, textAlign: 'left'}}>Accept</Text><Text style={{flex: 1, paddingVertical:50, backgroundColor:'red', left:0, right:0,textAlign:'right'}}>Reject</Text>
              </View>
              <View>
                  <Text style={{left:0, right:0, paddingVertical:50,borderWidth:1, backgroundColor:'grey'}}>Notification</Text>
              </View>
            </SwipeRow>
          );
        }}
      />
    );
  }
}
AppRegistry.registerComponent('SampleApp', () => SampleApp);

向左滑动

向右滑动

【问题讨论】:

    标签: listview reactjs react-native swipe react-native-listview


    【解决方案1】:

    这是我扩展 SwipeListViewSwipeRow 的解决方案。

    实现了什么:

    • 滑动向左向右事件处理。
    • 向左/向右滑动时整行的颜色变化(绿色“透明”红色)
    • 使颜色过渡渐变(100% 绿色“透明”100% 红色)

    index.ios.js:

    import React, { Component } from 'react';
    import { AppRegistry, StyleSheet, Text, View, ListView } from 'react-native';
    var SwipeListViewNotification = require('./SwipeListViewNotification.js').default;
    var SwipeRowNotification = require('./SwipeRowNotification.js').default;
    var data = [ { id:0, notification: true, },{ id:1, notification: false, },{ id:2, notification: false, } ];
    
    class SampleApp extends Component {
    
      render() {
        var ds = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
        return (
          <SwipeListViewNotification
            dataSource={ds.cloneWithRows(data)}
            onRowClose={() => {console.log("list.onRowClose")}}
            onRowOpen={() => {console.log("list.onRowClose")}}
            renderRow={ (data, secId, rowId, rowMap) => {
              return (
                <SwipeRowNotification onOpenLeft={() => console.log("ACCEPT")} onOpenRight={() => console.log("REJECT")}>
                  <View></View>
                  <View>
                      <Text style={{left:0, right:0, paddingVertical:50,borderWidth:1, backgroundColor:'grey'}}>Notification</Text>
                  </View>
                </SwipeRowNotification>
              );
            }}
          />
        );
      }
    }
    AppRegistry.registerComponent('SampleApp', () => SampleApp);
    

    SwipeListViewNotification.js:

    'use strict';
    
    import React, {
        PropTypes,
    } from 'react';
    import { SwipeListView } from 'react-native-swipe-list-view';
    
    class SwipeListViewNotification extends SwipeListView {
    
      constructor(props) {
        super(props);
      }
    
      renderRow(rowData, secId, rowId, rowMap) {
            const Component = this.props.renderRow(rowData, secId, rowId, rowMap);
            if (Component.type.name === 'SwipeRowNotification') {
                return React.cloneElement(
                    Component,
                    {
                        ...Component.props,
                        ref: row => this._rows[`${secId}${rowId}`] = row,
                        onRowOpen: _ => this.onRowOpen(secId, rowId, this._rows),
                        onRowClose: _ => this.props.onRowClose && this.props.onRowClose(secId, rowId, this._rows),
                        onRowPress: _ => this.onRowPress(`${secId}${rowId}`),
                        setScrollEnabled: enable => this.setScrollEnabled(enable)
                    }
                );
            } else {
                return super.renderRow(rowData, secId, rowId, rowMap)
            }
        }
    
      render() {
        return (
          super.render()
        )
      }
    }
    
    export default SwipeListViewNotification;
    

    SwipeRowNotification.js:

    'use strict';
    
    import React, {
        PropTypes,
    } from 'react';
    import { SwipeRow } from 'react-native-swipe-list-view';
    
    class SwipeRowNotification extends SwipeRow {
    
      constructor(props) {
        super(props);
        super.state = {
          color: 'transparent'
        };
      }
    
    
    
    manuallySwipeRow(toValue) {
        if (toValue == 0) {
          super.setState({color: 'transparent',opacity: 1});
        }
        if (toValue == this.props.leftOpenValue) {
          this.props.onOpenLeft(toValue);
        } else if (toValue == this.props.rightOpenValue) {
          this.props.onOpenRight(toValue);
        }
            super.manuallySwipeRow(toValue);
        }
    
      handlePanResponderMove(e, gestureState) {
        super.handlePanResponderMove(e, gestureState);
        const { moveX } = gestureState;
        const translateX = this.state.translateX._value;
        var opacity;
        if (translateX == 0) {
          opacity = 1;
          super.setState({color: 'transparent',opacity});
        } else if (translateX < this.props.leftOpenValue && translateX >= 0) {
          opacity = (0.5-(translateX/this.props.leftOpenValue)/2)+0.5;
          super.setState({color: this.props.leftColor,opacity});
        } else if (translateX < 0 && translateX > this.props.rightOpenValue) {
          opacity = (0.5-(translateX/this.props.rightOpenValue)/2)+0.5;
          super.setState({color: this.props.rightColor,opacity});
        } else if ( translateX >= this.props.leftOpenValue) {
          opacity = 0.5;
          super.setState({color: this.props.leftColor,opacity});
        } else if (translateX <= this.props.rightOpenValue) {
          opacity = 0.5;
          super.setState({color: this.props.rightColor,opacity});
        }
    
      }
    
      renderRowContent() {
            if (this.state.dimensionsSet) {
                return (
                    <Animated.View
                        {...this._panResponder.panHandlers}
                        style={{
                            transform: [
                                {translateX: this.state.translateX}
                            ]
                        }}
                    >
                        {this.renderVisibleContent()}
                    </Animated.View>
                );
            } else {
                return (
                    <Animated.View
                        {...this._panResponder.panHandlers}
                        onLayout={ (e) => this.onContentLayout(e) }
                        style={{
                            transform: [
                                {translateX: this.state.translateX}
                            ]
                        }}
                    >
                        {this.renderVisibleContent()}
                    </Animated.View>
                );
            }
        }
    
      renderVisibleContent() {
            const onPress = this.props.children[1].props.onPress;
    
            if (onPress) {
                const newOnPress = _ => {
                    this.onRowPress();
                    onPress();
                }
                return React.cloneElement(
                    this.props.children[1],
                    {
                        ...this.props.children[1].props,
                        onPress: newOnPress,
              style: {backgroundColor: this.state.color}
                    }
                );
            }
    
            return (
              <TouchableOpacity
                activeOpacity={1}
                onPress={ _ => this.onRowPress() }
              >
                <View style={{backgroundColor: this.state.color}}>
                  <View style={{opacity:this.state.opacity}}>{this.props.children[1]}</View>
                </View>
              </TouchableOpacity>
    )
    
        }
    
    
      render() {
        return (
                <View>
                    <View></View>
            <View>
                        {this.renderRowContent()}
            </View>
                </View>
            );
      }
    }
    
    SwipeRowNotification.propTypes = {
        onOpenLeft: PropTypes.func,
      onOpenRight: PropTypes.func,
      leftColor: PropTypes.string,
      rightColor: PropTypes.string,
    }
    
    SwipeRowNotification.defaultProps = {
      leftColor: 'red',
      rightColor: 'green',
    }
    
    export default SwipeRowNotification;
    

    【讨论】:

    • 帅哥,这个有什么世博小吃吗?
    • @LucianoSantos 目前不使用博览会
    • 不使用它有更好的伙伴吗?纯反应原生更好?我对这一切都是新手..
    • @LucianoSantos pure react native 给你更多的控制权,expo 似乎有更好的开发者体验。取决于你在做什么类型的项目。
    猜你喜欢
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    相关资源
    最近更新 更多