javascript - 如何在 ListView 上实现滑动功能(react-native)?

标签 javascript listview react-native mobile-development

我有元素 list 。我正在使用ListView为此,我需要能够通过向左或向右滑动来删除任何行。

我可以从哪里开始?

最佳答案

如果您愿意,请关注this guide它使用 React Native Swipeout .

否则,这是我的 SwipeList 和 SwipeListRow 组件。我部分使用我的图书馆 Cairn用于样式,但如果您愿意的话,应该可以轻松地将其转换为普通的 React 样式表:

SwipeList.js

import React from 'react';
import { Text, ListView } from 'react-native';
import styleContext from 'app/style';

const style = styleContext.extend({
    listViewSection: {
        paddingVertical: 10,
        paddingLeft: 15,
        backgroundColor: '$greyDefault'
    },

    'text.listViewSection': {
        color: '$greyMid',
        fontSize: 16,
        marginLeft: 5
    }
});

function SwipeList({ dataSource, renderRow }) {
    function renderSectionHeader(sectionData, sectionId) {
        return (
            <View {...style('listViewSection')}>
                <Text {...style('text.listViewSection')}>{sectionId.toUpperCase()}</Text>
            </View>
        );
    }

    if (!dataSource.rowIdentities.length) {
        return (
            <Text>No items found.</Text>
        );
    }

    return (
        <ListView
            dataSource={dataSource}
            automaticallyAdjustContentInsets={false}
            directionalLockEnabled
            keyboardShouldPersistTaps={false}
            keyboardDismissMode={'on-drag'}
            renderSectionHeader={renderSectionHeader}
            renderRow={renderRow} />
    );
}

SwipeList.propTypes = {
    dataSource: React.PropTypes.shape({
        rowIdentities: React.PropTypes.array.isRequired
    }).isRequired,
    renderRow: React.PropTypes.func.isRequired
};

export default SwipeList;

SwipeListRow.js

import React from 'react';
import {
    View,
    Text,
    ScrollView,
    Animated,
    Dimensions
} from 'react-native';

import styleContext from 'app/style';

const { width } = Dimensions.get('window');
const style = styleContext.extend({
    swipeMessage: {
        position: 'absolute',
        top: 0,
        height: 75,
        justifyContent: 'center',
        alignItems: 'center'
    },

    itemContainer: {
        width
    }
});

const WHITE = 0;
const GREEN = 1;
const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);

class SwipeListRow extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            color: new Animated.Value(WHITE)
        };
    }

    animateScroll = (e) => {
        const threshold = width / 5;
        let x = e.nativeEvent.contentOffset.x;
        let swiped = null;

        x = x * -1;

        if (x > -50 && this.swiped !== WHITE) {
            swiped = WHITE;
        } else if (x < -50 && x > -threshold && this.swiped !== GREEN) {
            swiped = GREEN;
        }

        if (swiped !== null) {
            this.swiped = swiped;

            Animated.timing(this.state.color, {
                toValue: swiped,
                duration: 200
            }).start();
        }
    }

    takeAction = () => {
        if (this.swiped) {
            Animated.timing(this.state.color, {
                toValue: WHITE,
                duration: 200
            }).start();

            this.props.onSwipe();
        }
    }

    render() {
        const { swipeEnabled, swipeMessage, children } = this.props;
        const bgColor = this.state.color.interpolate({
            inputRange: [
                WHITE,
                GREEN
            ],
            outputRange: [
                'rgb(255, 255, 255)',
                'rgb(123, 204, 40)'
            ]
        });

        return (
            <View>
                <AnimatedScrollView
                    horizontal
                    directionalLockEnabled
                    automaticallyAdjustContentInsets={false}
                    onScroll={this.animateScroll}
                    scrollEventThrottle={16}
                    scrollEnabled={swipeEnabled}
                    onMomentumScrollBegin={this.takeAction}
                    style={[{ flex: 1 }, { backgroundColor: bgColor }]}>
                    <View>
                        <View {...style('itemContainer')}>
                            {children}
                        </View>
                        <View
                            {...style(
                                'swipeMessage',
                                [{ width: width / 5, right: -width / 5 - 20 }]
                            )}>
                            <Text {...style('text.bold text.white')}>{swipeMessage}</Text>
                        </View>
                    </View>
                </AnimatedScrollView>
            </View>
        );
    }
}

SwipeListRow.propTypes = {
    children: React.PropTypes.node.isRequired,
    onSwipe: React.PropTypes.func.isRequired,
    swipeEnabled: React.PropTypes.bool.isRequired,
    swipeMessage: React.PropTypes.string.isRequired
};


export default SwipeListRow;

有了这些组件,现在您所要做的就是传入所需的数据源,就像传递到普通 ListView 一样,如 ListView component documentation 中所述。 .

    <SwipeList
        dataSource={dataSource}
        renderRow={(item) => (
            <SwipeListRow
                key={item.id}
                swipeMessage={'Delete Item'}
                onSwipe={() => deleteItem(item)}
                swipeEnabled={true}>
                <<< INSERT DISPLAY OF ROW HERE >>>
            </SwipeListRow>
        )} />

关于javascript - 如何在 ListView 上实现滑动功能(react-native)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37393453/

相关文章:

javascript - 通过 json 中的键访问值会抛出 undefined

ios - React Native ListView 加载缓慢

c# - Foreach 遍历所有 listView 项目

android - 应用程序启动时出现错误 "Could not get BatchedBridge, make sure your bundle is packaged properly"

javascript - 页面滚动位置对应的CSS动画

javascript - ext js改变面板的颜色为渐变

javascript - 超时后调用 Knockout JS Extender 函数

android - Recyclerview 行内的 GoogleMap

ios - 初始化新的 React Native 项目并替换为 App Store 中当前的 React Native 项目

javascript - 单击标记时尝试导航到另一个屏幕