Я нашел решение на основе 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) в моем классе, но ничего не изменилось.