如何解决如何仅在特定条件下实现自定义BackHandler行为?
我的应用程序中有一个平面列表,我希望使用户能够将长按中的特定列表项标记为选中,并提供一个删除按钮以一次性删除多个项目。这些是我期望的行为。
- 如果未选择单位列表中的任何项目,则按一个项目将打开一个包含项目详细信息的新屏幕,然后使用“后退”按钮将您带回到该单位列表。
- 如果未选择任何项目,则长按一个项目会将其标记为已选择。选择任何特定项目后按下的每个项目都标记为已选择,而不是打开详细信息屏幕。
- 已经选择然后按下的项目将变为未选择状态。
- 如果选择了任意数量的项目,则会显示一个删除按钮,并且按下后退按钮会取消选择所有项目。
我已经能够实现前三个行为中的大多数,但是我完全迷失了Back Handler。这是我的组件,仅带有简短的相关代码。仅显示包含选择要删除的项目的状态数组和用作Flatlist的RenderItem属性的listItem。
const Home = (props) => {
const [deleteItems,setDeleteItems] = useState([]);
const renderItem = ({ item }) => {
let bb_OR_ub = item.useBy ? 'Use By ' : 'Best Before '
let exp_check = CheckExp(item,1);
let listStyle = {};
if (exp_check === -1)
listStyle = { backgroundColor: '#ff9ea5' }
else if (exp_check === 0)
listStyle = { backgroundColor: '#fff185' }
if (deleteItems.indexOf(item.name) != -1) {
listStyle = { opacity: 0.3 }
}
return (
<ListItem
containerStyle={listStyle}
badge={
exp_check !== 1 ?
exp_check === -1 ? { status: 'error',value: `!` } : {
status: 'warning'
} : null
}
title={item.name}
subtitle={bb_OR_ub + item.date}
bottomDivider
leftAvatar={{ source: require('../shared/cexp.png'),imageProps: { resizeMode: 'contain' } }}
onPress={() => {
if (deleteItems.length == 0)
navigate('ExpiryDetails',{ item })
else {
setDeleteItems([...deleteItems,item.name])
}
}}
onLongPress={() => {
if (deleteItems.indexOf(item.name) == -1 || deleteItems.length == 0) {
setDeleteItems([...deleteItems,item.name])
}
else {
setDeleteItems(deleteItems.filter(el => el != item.name))
}
}} />
);
}
解决方法
react-native提供的BackHandler
允许您订阅被按下的后退按钮。提供给后处理程序的回调可以提供true
(当不应触发默认行为时)或false
(当允许继续默认行为时)。
对于您的情况,我们希望在选择了项目时在背面具有自定义行为,这时我们要取消选择所有项目。
我调整了您的代码以引入BackHandler
,并取消选择背面被按下的任何项目
const Home = (props) => {
const [deleteItems,setDeleteItems] = useState([]);
// Subscribe to BackHandler once the component is mounted
// or when deletedItems changes
useEffect(() => {
const handler = BackHandler.addEventListener('hardwareBackPress',() => {
// If no deleted items: we return false
if (!deletedItems.length) {
return false;
}
// clear the selected items,and indicate that the back if handled
setDeletedItems([]);
return true;
});
// unsubscribe when component unmounts
return () => {
handler.remove();
};
},[deletedItems]);
const renderItem = ({ item }) => {
let bb_OR_ub = item.useBy ? 'Use By ' : 'Best Before '
let exp_check = CheckExp(item,1);
let listStyle = {};
if (exp_check === -1)
listStyle = { backgroundColor: '#ff9ea5' }
else if (exp_check === 0)
listStyle = { backgroundColor: '#fff185' }
if (deleteItems.indexOf(item.name) != -1) {
listStyle = { opacity: 0.3 }
}
return (
<ListItem
containerStyle={listStyle}
badge={
exp_check !== 1 ?
exp_check === -1 ? { status: 'error',value: `!` } : {
status: 'warning'
} : null
}
title={item.name}
subtitle={bb_OR_ub + item.date}
bottomDivider
leftAvatar={{ source: require('../shared/cexp.png'),imageProps: { resizeMode: 'contain' } }}
onPress={() => {
if (deleteItems.length == 0)
navigate('ExpiryDetails',{ item })
else {
setDeleteItems([...deleteItems,item.name])
}
}}
onLongPress={() => {
if (deleteItems.indexOf(item.name) == -1 || deleteItems.length == 0) {
setDeleteItems([...deleteItems,item.name])
}
else {
setDeleteItems(deleteItems.filter(el => el != item.name))
}
}} />
);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。