React Native - 长按并平移/滑动以选择元素

问题描述 投票:0回答:1

我试图创建一个长按和滑动/平移来聚焦/选择元素。

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

const GestureItemRenderer = (
  props: ViewProps & {
    items: number[];
    selectedItem: number | null;
    setViewItems: React.Dispatch<React.SetStateAction<boolean>>;
    handleSelection: (item: number) => void;
  },
) => {
  const itemArea = 30;
  const [focusedItem, setFocusedItem] = useState<number | null>(null);

  const handleFocus = (item: number | null) => {
    setFocusedItem(item);
  };

  const styles = StyleSheet.create({
    container: {
      flexDirection: 'row',
      padding: 6,
      gap: 6,
      borderWidth: 1,
      borderColor: 'red',
    },
    itemContainer: {
      borderWidth: 1,
      borderColor: 'black',
      height: itemArea,
      width: itemArea,
    },
    selectedItem: {
      backgroundColor: 'red',
    },
    focusedItem: {
      backgroundColor: 'blue',
    },
  });

  return (
    <View style={styles.container} {...props}>
      {props.items.map((item, index) => (
        <TouchableOpacity
          onPress={() => props.handleSelection(item)}
          style={[
            styles.itemContainer,
            item === props.selectedItem && styles.selectedItem,
            item === focusedItem && styles.focusedItem,
          ]}
          key={index}>
          <Text>{item}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
};

const SelectorComponent = () => {
  const items = [1, 2, 3, 4, 5, 6, 7, 8];

  const [selectedItem, setSelectedItem] = useState<number | null>(null);
  const [viewItems, setViewItems] = useState(false);

  const styles = StyleSheet.create({
    container: {},
  });

  const handleSelectionFromSelectButton = () => {
    if (selectedItem) {
      setSelectedItem(null);
    } else {
      setSelectedItem(items[0]);
    }
  };

  const handleSelection = (value: number) => {
    setSelectedItem(value);
    setViewItems(false);
  };

  const handleLongPress = () => {
    // I want these functionalities when the user long presses:
    // If user long presses on the select button and doesn't move their finger, show the item and let user lift their finger to select it
    // If user long presses on the select button and moves their finger, show the item and let user move their finger inside the gesture area to focus on an item and lift their finger to select it
    // If user long presses on the select button and moves their finger outside the gesture area, unfocus the item
    // If user long presses on the select button and moves their finger outside the gesture area and lifts their finger, unfocus the item and hide the gesture area
    // If user long presses on the select button and moves their finger outside the gesture area and moves their finger back inside the gesture area, show the gesture area and let user move their finger inside the gesture area to focus on an item and lift their finger to select it
  };

  return (
    <View style={styles.container}>
      {viewItems && (
        <GestureItemRenderer
          items={items}
          selectedItem={selectedItem}
          setViewItems={setViewItems}
          handleSelection={handleSelection}
        />
      )}
      <TouchableOpacity
        onPress={handleSelectionFromSelectButton}
        onLongPress={handleLongPress}>
        <Text>Select</Text>
      </TouchableOpacity>
    </View>
  );
};

export default SelectorComponent;

我希望每当我长按选择按钮时添加这些功能

  • 如果用户长按选择按钮并且不移动手指,则显示该项目并让用户抬起手指来选择它
  • 如果用户长按选择按钮并移动手指,则显示该项目并让用户在手势区域内移动手指以聚焦于某个项目,然后抬起手指以选择它
  • 如果用户长按选择按钮并将手指移出手势区域,则取消项目的焦点
  • 如果用户长按选择按钮并将手指移出手势区域并抬起手指,则取消项目焦点并隐藏手势区域
  • 如果用户长按选择按钮并将手指移出手势区域并将手指移回手势区域内,则显示手势区域并让用户在手势区域内移动手指以聚焦于某个项目并抬起手指选择它

我尝试在

GestureItemRenderer
上添加 panresponder,但组件渲染时 pan 不起作用。

        <GestureItemRenderer
          items={items}
          selectedItem={selectedItem}
          setViewItems={setViewItems}
          handleSelection={handleSelection}
          {...panResponder.panHandlers}
        />

任何人都可以建议我应该做什么,或者如何实现这个功能?或者一些可能有帮助的代码?我计划创建类似 facebook/linkedin 应用程序的反应按钮的东西。

谢谢

javascript react-native swipe gesture long-press
1个回答
0
投票

如果别人是通过搜索引擎来到这里的,可以尝试使用 Pressable https://reactnative.dev/docs/pressable 来包装一个组件,它有 onLongPress 功能。

© www.soinside.com 2019 - 2024. All rights reserved.