Смахивание предмета в SwipeList не работает - PullRequest
0 голосов
/ 11 марта 2020

Я нашел решение на основе swipelist ( здесь ), и когда я тестировал его на своем телефоне, оно отлично работает.

Затем я захотел попробовать его в своем приложении, и из-за этого жест смахивания становится запаздывающим (мне приходится несколько раз смахивать, и когда я делаю это медленно, я вижу пролистывание долгое время после моего жеста).

Я просто взял swip_to_delete. js из пример закуски и добавь его в мой проект. Затем я вызываю его из одного из моих классов.

Вот мой класс, выполняющий вызов функции:

// components/Money.js

import React from 'react'
import { StyleSheet, View, Image, Platform, FlatList, ActivityIndicator, Text } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler'
import { Ionicons } from '@expo/vector-icons'
import StuffData from '../dbaccess/StuffData'
import MoneyData from '../dbaccess/MoneyData'
import SwipeValueBasedUi from '../functions/SwipeValueBasedUI'

class LendList extends React.Component {

    constructor(props) {
        super(props)

        this.state = { 
            moneyList: [],
            stuffList: [],
            isLoading: true
        }
    }

    _getData() {
        const type = this.props.route.params?.type ?? 'defaultValue'

        if (type === 'Money'){
            let myMoney = new MoneyData()
            myMoney.getMoneyData().then(val => {
                this.setState({
                    moneyList: val,
                    isLoading: false,
                })
            })

        } else if (type === 'Stuff'){
            let myStuff = new StuffData()
            myStuff.getStuffData().then(val => {
                this.setState({
                    stuffList: val,
                    isLoading: false,
                })
            })
        }
    }

    _updateNavigationParams() {
        const navigation = this.props.navigation
        const type = this.props.route.params?.type ?? 'defaultValue'

        let addIconName
        addIconName = ((Platform.OS == 'android') ? 'md-add' : 'ios-add')


        if (Platform.OS === "ios" && type !== 'People'){
            navigation.setOptions({
                        headerRight: () => <TouchableOpacity style={styles.add_touchable_headerrightbutton}
                                        onPress={() => this._addItem()}>
                                        <Ionicons name={addIconName} style={styles.add_image} />
                        </TouchableOpacity>
                })
            }
    }

    componentDidMount(){
        this._updateNavigationParams()
        this._getData()
    }

    _addItem = () => {
        const type = this.props.route.params?.type ?? 'defaultValue'

        if (type === 'Money'){
            this.props.navigation.navigate('AddMoney')
        } else {
            this.props.navigation.navigate('AddStuff')
        }
    }

    //Android dedicated
    _displayFloatingActionButton() {
        const type = this.props.route.params?.type ?? 'defaultValue'

        if (Platform.OS === 'android' && type !== 'People'){
            return(
            <TouchableOpacity style={styles.add_touchable_floatingactionbutton}
                onPress={() => this._addItem()}>
                <Image style={styles.add_image} source={require('../assets/icons/ic_add.png')}/>
            </TouchableOpacity>
            )
        }
    }

    _checkData(){
        this._displayDataList()
    }

    _displayDetailsForMyItem = (idItem, type) => {
        this.props.navigation.navigate('ItemDetails', { idMyItem: idItem, type: type })
    }

    _displayDataList(){
        const type = this.props.route.params?.type ?? 'defaultValue'

        if (type === 'Money') {
            return this.state.moneyList
        } else if (type === 'Stuff') {
            return this.state.stuffList
        } else {
            return this.state.peopleList
        }
    }

    _deleteItem = (idItem, type) => {
        if (type === 'Money') {
            let myMoney = new MoneyData()

            myMoney.deleteMoney(idItem)
            this.setState({
                moneyList: this.state.moneyList.filter(item => item.key != idItem)
            })
        } else {
            let myStuff = new StuffData()

            myStuff.deleteStuff(idItem)
            this.setState({
                stuffList: this.state.stuffList.filter(item => item.key != idItem)
            })
        }

        alert(type + ' deleted')

    }

    _getTotal() {
        let total = 0
        const type = this.props.route.params?.type ?? 'defaultValue'

        if (type === 'Stuff') {
            let myStuff = new StuffData();
            myStuff.totalStuff().then(val => { this.setState({
                totalQuantity: val
                })
            })
            .catch(error => {
                console.error(error)
            })
        } else {
            let myMoney = new MoneyData();
            myMoney.totalMoney().then(val => { this.setState({
                totalMoney: val
                })
            })
            .catch(error => {
                console.error(error)
            })
        }
    }

    render(){
        const type = this.props.route.params?.type ?? 'defaultValue'
        const total = this._getTotal()

        if(this.state.isLoading){
            return(
              <View style={styles.activity}>
                <ActivityIndicator size="large" color="#FB5B5A"/>
              </View>
            )
        }

        return(
            <View style={styles.main_container}>
                <View style={styles.title_container}>
                    <Image source={require('../assets/icons/cadre.png')} style={styles.cadre} />
                    <Text style={styles.header_text}>
                        {(type === 'Money') ? this.state.totalMoney + ' €' : this.state.totalQuantity}
                    </Text>
                </View>
                <SwipeValueBasedUi />
            </View>
        )
    }
}

const styles=StyleSheet.create({
    main_container: {
        flex: 1,
        backgroundColor: '#003F5C'
    },
    title_container: {
        justifyContent: 'center',
        alignItems: 'center',
        marginTop: 40,
        marginBottom: 40
    },
    header_text: {
        textAlign: 'center',
        fontSize: 35,
        color: 'white',
    },
    cadre: {
        position: 'absolute',
        marginRight: 10,
    },
    add_touchable_headerrightbutton: {
        marginRight: 8
    },
    add_image: {
        marginRight: 10,
        fontSize: 30,
        color: 'white'
    },
    add_touchable_floatingactionbutton: {
        position: 'absolute',
        width: 60,
        height: 60,
        right: 30,
        bottom: 30,
        borderRadius: 30,
        backgroundColor: '#e91e63',
        justifyContent: 'center',
        alignItems: 'center'
    },
    list: {
    },
    activity: {
        position: 'absolute',
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#003F5C'
      }
})

export default LendList

, а вот функция, которую я вызываю:

// functions/SwipeValueBasedUI.js

import React, { useState } from 'react';
import {
    Animated,
    Image,
    StyleSheet,
    Text,
    TouchableOpacity,
    TouchableHighlight,
    View,
} from 'react-native';

import { SwipeListView } from 'react-native-swipe-list-view';

const rowSwipeAnimatedValues = {};
Array(10)
    .fill('')
    .forEach((_, i) => {
        rowSwipeAnimatedValues[`${i}`] = new Animated.Value(0);
    });

export default function SwipeValueBasedUi() {
    const [listData, setListData] = useState(
        Array(10)
            .fill('')
            .map((_, i) => ({ key: `${i}`, text: `item #${i}` }))
    );

    const closeRow = (rowMap, rowKey) => {
        if (rowMap[rowKey]) {
            rowMap[rowKey].closeRow();
        }
    };

    const deleteRow = (rowMap, rowKey) => {
        closeRow(rowMap, rowKey);
        const newData = [...listData];
        const prevIndex = listData.findIndex(item => item.key === rowKey);
        newData.splice(prevIndex, 1);
        setListData(newData);
    };

    const onRowDidOpen = rowKey => {
        console.log('This row opened', rowKey);
    };

    const onSwipeValueChange = swipeData => {
        const { key, value } = swipeData;
        rowSwipeAnimatedValues[key].setValue(Math.abs(value));
    };

    const renderItem = data => (
        <TouchableHighlight
            onPress={() => console.log('You touched me')}
            style={styles.rowFront}
            underlayColor={'#AAA'}
        >
            <View>
                <Text>I am {data.item.text} in a SwipeListView</Text>
            </View>
        </TouchableHighlight>
    );

    const renderHiddenItem = (data, rowMap) => (
        <View style={styles.rowBack}>
            <Text>Left</Text>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnLeft]}
                onPress={() => closeRow(rowMap, data.item.key)}
            >
                <Text style={styles.backTextWhite}>Close</Text>
            </TouchableOpacity>
            <TouchableOpacity
                style={[styles.backRightBtn, styles.backRightBtnRight]}
                onPress={() => deleteRow(rowMap, data.item.key)}
            >
                <Animated.View
                    style={[
                        styles.trash,
                        {
                            transform: [
                                {
                                    scale: rowSwipeAnimatedValues[
                                        data.item.key
                                    ].interpolate({
                                        inputRange: [45, 90],
                                        outputRange: [0, 1],
                                        extrapolate: 'clamp',
                                    }),
                                },
                            ],
                        },
                    ]}
                >
                    <Image
                        source={require('../assets/icons/ic_settings.png')}
                        style={styles.trash}
                    />
                </Animated.View>
            </TouchableOpacity>
        </View>
    );

    return (
            <SwipeListView
                data={listData}
                renderItem={renderItem}
                renderHiddenItem={renderHiddenItem}
                leftOpenValue={75}
                rightOpenValue={-150}
                previewRowKey={'0'}
                previewOpenValue={-40}
                previewOpenDelay={3000}
                onRowDidOpen={onRowDidOpen}
                onSwipeValueChange={onSwipeValueChange}
            />
    );
}

const styles = StyleSheet.create({
    container: {
        backgroundColor: 'white',
        flex: 1,
    },
    backTextWhite: {
        color: '#FFF',
    },
    rowFront: {
        alignItems: 'center',
        backgroundColor: '#CCC',
        borderBottomColor: 'black',
        borderBottomWidth: 1,
        justifyContent: 'center',
        height: 50,
    },
    rowBack: {
        alignItems: 'center',
        backgroundColor: '#DDD',
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        paddingLeft: 15,
    },
    backRightBtn: {
        alignItems: 'center',
        bottom: 0,
        justifyContent: 'center',
        position: 'absolute',
        top: 0,
        width: 75,
    },
    backRightBtnLeft: {
        backgroundColor: 'blue',
        right: 75,
    },
    backRightBtnRight: {
        backgroundColor: 'red',
        right: 0,
    },
    trash: {
        height: 25,
        width: 25,
    },
});

Я пытался добавить жест смахивания (весь код в SwipeValueBasedUI. js) в моем классе, но ничего не изменилось.

...