gpt4 book ai didi

javascript - React Native FlatList : Select all Items and run 'OnPress'

转载 作者:行者123 更新时间:2023-12-02 18:18:35 25 4
gpt4 key购买 nike

我正在使用react-native-bouncy-checkboxFlatlist

I have created an array object which has id, name, amount.

So far I have achieved:

  • User can select individual items from the Flatlist, and it will add the amount and display itas total amount.

  • User can also edit the amount they have selected using TextInput.


但是,我正在尝试创建“全选”功能。

因此,当用户按“全选”或点击“复选框”时,它应该:

  1. 从 FlatList 中选择所有项目
  2. 添加总金额
  3. 允许用户单独编辑所有选定的金额
  4. 更新复选框以显示它已被选中。

到目前为止,我已经尝试让所有“复选框”显示在按下“全选”文本或按下“复选框”(选择所有文本旁边)时它被选中。

过去几个小时我一直试图让它发挥作用,但未能成功。因此,非常欢迎有关此问题的任何帮助。


代码片段和应用程序屏幕截图如下:

代码示例:

import 'react-native-gesture-handler';
import React, { useState, useEffect, Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, FlatList } from 'react-native';
import { Button, Divider, TextInput } from 'react-native-paper';
import BouncyCheckbox from 'react-native-bouncy-checkbox';
import TextInputMask from 'react-native-text-input-mask';

function AccountMultiplePayment({ navigation }) {
const [apiData, setApiData] = useState([
{
id: 1,
name: 'John',
address: 'address 1',
amount: '79.90',
},
{
id: 2,
name: 'Simon',
address: 'address 2',
amount: '35.50',
},
{
id: 3,
name: 'Tim',
address: 'address 3',
amount: '15.50',
},
{
id: 4,
name: 'Rob',
address: 'address 4',
amount: '33.33',
},
{
id: 5,
name: 'Sarah',
address: 'address 5',
amount: '77.77',
},
])

const [billPaymentAmount, setBillPaymentAmount] = useState({})
const [selectedBill, setSelectedBill] = useState([]);
const [totalPaymentAmount, setTotalPaymentAmount] = useState(0);

const computeBillPaymentAmount = () => {
let newBillPaymentAmount = {}

apiData.forEach(({ id, amount }) => {
newBillPaymentAmount[id] = amount
})

return newBillPaymentAmount
}

const computeTotalPaymentAmount = () => {
let total = 0

selectedBill.forEach(id => {
total += parseFloat(billPaymentAmount[id])
})

// Prevent NaN issue, because once user delete amount will become empty string
return total ? total : 0
}

useEffect(() => {
setBillPaymentAmount(computeBillPaymentAmount())
}, [apiData])

useEffect(() => {
setTotalPaymentAmount(computeTotalPaymentAmount())
}, [selectedBill, billPaymentAmount])

const [checked, setChecked] = useState(false);

return (
<>
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
style={{ alignItems: 'center', paddingVertical: 10 }}
onPress={() => setChecked(!checked)}
>
<Text style={{ color: 'black', fontSize: 25 }}>Select All</Text>
</TouchableOpacity>
<BouncyCheckbox
isChecked={checked}
fillColor={'green'}
unfillColor={'#FFFFFF'}
onPress={() => {
setChecked(!checked)
}}
/>
</View>
<FlatList
data={apiData}
renderItem={({ item }) => {
return (
<View style={{ flexDirection: 'row' }}>
<View style={[styles.subHeaderContainer, { flex: 1 }]}>
<Text
style={[
styles.defaultText,
{ fontWeight: 'bold', fontSize: 16 },
]}>
{item.name}
</Text>
<Divider style={{ marginVertical: 5 }} />
<View style={{ flexDirection: 'row' }}>
<Text
style={[styles.defaultText, { fontWeight: 'bold', flex: 2 }]}>
Total Payable Amount:
</Text>
<View style={{ flex: 1 }}>
<TextInput
value={billPaymentAmount[item.id]}
onChangeText={value => setBillPaymentAmount({ ...billPaymentAmount, [item.id]: value })}
keyboardType={'numeric'}
mode={'outlined'}
label={'RM'}
dense={true}
render={props =>
<TextInputMask
{...props}
mask='[9990].[99]'
/>
}
/>
</View>
</View>
</View>
<BouncyCheckbox
isChecked={checked}
fillColor={'green'}
unfillColor={'#FFFFFF'}
onPress={() => {
if (selectedBill.includes(item.id)) {
setSelectedBill(selectedBill.filter(value => value !== item.id))
} else {
setSelectedBill([...selectedBill, item.id])
}
}}
/>
</View>
);
}}
keyExtractor={item => item.id}
removeClippedSubviews={false}
/>
{
<>
<View
style={{
paddingVertical: 10,
paddingHorizontal: 20,
flexDirection: 'row',
backgroundColor:'blue'
}}>
<Text
style={{ color: 'white', flex: 1, fontWeight: 'bold', fontSize: 18 }}>
Total Amount:{' '}
</Text>
<View>
<Text style={{ color: 'white', fontWeight: 'bold', fontSize: 24 }}>
RM {totalPaymentAmount.toFixed(2)}
</Text>
{totalPaymentAmount <= 0 ? null : (
<TouchableOpacity
onPress={() => {
//navigation.goBack();
navigation.goBack();
navigation.navigate('Account');
}}>
<Text>Reset</Text>
</TouchableOpacity>
)}
</View>
</View>

<Button
mode={'contained'}
color={'limegreen'}
style={{
borderRadius: 5,
marginHorizontal: 20,
marginVertical: 10,
justifyContent: 'center',
}}
labelStyle={{ color: 'white', padding: 10 }}
uppercase={false}
onPress={() => { }}
disabled={totalPaymentAmount <= 0 ? true : false}>
<Text>Pay Bill</Text>
</Button>
</>
}
</>
);
}
class Account extends Component {
constructor(props) {
super(props);
this._isMounted = false;
this.state = {

};
}

render() {
return (
<>
{<AccountMultiplePayment {...this.props} {...this.navigation} />}
</>
);
}
}

export default Account;

const styles = StyleSheet.create({
flex: {
flex: 1,
},
headerTitle: {
alignItems: 'center',
borderBottomLeftRadius: 25,
borderBottomRightRadius: 25,
paddingHorizontal: 20,
paddingVertical: 20,
},
subHeaderContainer: {
paddingVertical: 10,
paddingHorizontal: 20,
backgroundColor: 'white',
borderRadius: 10,
elevation: 5,
marginVertical: 5,
marginHorizontal: 10,
},
subHeaderTitle: {
color: 'white',
fontWeight: 'bold',
fontSize: 16,
backgroundColor: '#2c1855',
padding: 10,
borderRadius: 10,
},
defaultText: {
color: 'black',
},
});

这就是目前的样子。所有选中的项目都是单独选择的:

current app screenshot


这就是我想要实现的目标:

goal for this app

最佳答案

检查documentation of react-native-bouncy-checkbox后,以下内容很重要。

  1. isChecked确定默认的内部复选框状态。仅评估一次。
  2. check 状态处理由库内部处理。
  3. 我们希望自己处理这个问题,以便通过一次状态更改来选中所有复选框。为此,我们需要将 disableBuiltInState 属性设置为 true“如果您想手动处理 isChecked 属性并禁用内置处理”。

因此,我建议采用以下工作流程。

  1. isChecked 创建一个状态数组,其中包含每个元素的 bool 标志。
  2. 创建一个自定义 onPress 处理程序,它从 FlatList 获取索引作为参数。有了该索引,我们就可以将状态数组中的正确 bool 标志设置为 truefalse
  3. 如果按下全选,我们的onPress处理程序会将状态数组的所有 bool 标志设置为true。这将导致屏幕重新渲染,并且由于我们将 disableBuiltInState 属性设置为 true,react-native-bouncy-checkbox 将使用我们的自定义状态处理。

这是一个最小的工作示例。

// set inititial all to false, you might want some different initial state
const [checks, setChecks] = useState(Array.from({ length: apiData.length }, () => false))

const onCheck = React.useCallback(
(index) => {
let previous = [...checks]
previous[index] = !previous[index]
setChecks(previous)
},
[checks, setChecks]
)

const selectAll = React.useCallback(() => {
let previous = [...checks]
setChecks(previous.map(() => true))
}, [checks, setChecks])

return (
<View style={{ padding: 40, marginTop: 50 }}>
<FlatList
data={apiData}
renderItem={({ item, index }) => (
<View style={{ padding: 20 }}>
<BouncyCheckbox
isChecked={checks[index]}
fillColor={"green"}
unfillColor={"#FFFFFF"}
onPress={() => onCheck(index)}
disableBuiltInState={true}
/>
</View>
)}
keyExtractor={(item) => "" + item.id}
removeClippedSubviews={false}
/>
<TouchableOpacity onPress={selectAll}>
<Text style={{ fontSize: 20, color: "red" }}> Select All</Text>
</TouchableOpacity>
</View>
)

看起来如下。

enter image description here

全选会产生

enter image description here

由于您想要计算附加值(每个所选项目的总应付金额),我建议将 checks 状态添加到已实现的 useEffect 中。当checks状态改变时,这个useEffect将会被调用。您可以计算 checks 中 bool 标志为 true 的所有字段,并设置输入字段的状态。

关于javascript - React Native FlatList : Select all Items and run 'OnPress' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71203286/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com