React Native:捕获SwipeListView中的滑动事件

时间:2016-07-19 15:22:53

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

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

目标是通过滑动轻松解除推送式通知。当滑动到(绿色)和(红色)时,通知应逐渐改变颜色。在某个阈值(60)之后,应触发最终事件,在这种情况下接受(左)和拒绝(右),通知应该消失。

目前,这是我计划删除的按钮。

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

向左滑动

Swipe left

向右滑动

Swipe right

1 个答案:

答案 0 :(得分:0)

以下是扩展SwipeListViewSwipeRow的解决方案。

实施的内容:

  • 滑动事件处理。
  • 在向左/向右滑动时整行的
  • 颜色变化(绿色&lt; - &gt;“透明”&lt; - &gt;红色)
  • 使颜色过渡渐进(100%绿色&lt; - &gt;“透明”&lt; - &gt; 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;