【问题标题】:How to make reusable component for tabbar in react native如何在本机反应中为标签栏制作可重用组件
【发布时间】:2020-11-09 06:28:01
【问题描述】:

我有一个自定义标签栏组件,我想添加一个带动画的按钮,我想使其可重用,但我想不通。例如,我想将它用于 1,2,3... 等图标。我不想在组件本身中决定它。代码如下所示。

export const TabAddButton = () => {
  const windowWidth = useWindowDimensions().width;
  const buttonSize = useRef(new Animated.Value(1)).current;
  const mode = useRef(new Animated.Value(0)).current;
  const handlePress = () => {
    Animated.sequence([
      Animated.timing(buttonSize, {
        toValue: 0.95,
        duration: 5,
        useNativeDriver: true,
      }),
      Animated.timing(mode, {
        toValue: mode["_value"] === 0 ? 1 : 0,
        duration: 150,
        useNativeDriver: false,
      }),
    ]).start();
  }; 
  const lockX = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [windowWidth / 2 - 22, windowWidth / 2 - 22 - 60],
  });
  const lockY = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [-20, -75],
  });

  const noteX = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [windowWidth / 2 - 22, windowWidth / 2 - 22 + 60],
  });  
  return (
    <Box {...StyleSheet.absoluteFillObject} alignItems="center">
      <Animated.View
        style={[styles.secondaryView,{ left: lockX,top: lockY,}]}>
        <TouchableOpacity style={styles.secondaryButton}>
          <Feather name="lock" size={24} color="#FFF" />
        </TouchableOpacity>
      </Animated.View>

      <Animated.View style={[styles.secondaryView,{ left: lockX,top: noteY,}]}>
        <TouchableOpacity style={styles.secondaryButton}>
          <Foundation name="clipboard-notes" size={24} color="#FFF" />
        </TouchableOpacity>
      </Animated.View>

      <View style={[styles.button]}>
        <Animated.View style={[transform: [{ scale: buttonSize }]]}>
          <TouchableOpacity activeOpacity={1} onPress={handlePress} style={styles.primaryButton}
          >
            <Animated.View>
              <FontAwesome5 name="plus" size={24} color="#FFF" />
            </Animated.View>
          </TouchableOpacity>
        </Animated.View>
      </View>
    </Box>
  );
};

【问题讨论】:

  • 你要把它用作 react-navigation > BottomTabNavigator 的tabBarComponent 吗?
  • 是的,它适用于整个标签栏,但这只是一个按钮。我为问题添加了一个 gif
  • 那些弹出的图标会因活动路由而异......或者他们会被修复?
  • 不,每条路线都一样

标签: react-native reusability


【解决方案1】:

我会建议这样的事情

childButtons = [
  {
    isPrimary: false,
    iconName: 'lock',
    iconType: 'Feather',
    onPress: () => {},
  },
  {
    isPrimary: false,
    iconName: 'clipboard-notes',
    iconType: 'Foundation',
    onPress: () => {},
  },
  /** ... */
];

const AppTabSecondaryButton = ({ containerStyle, onPress, IconType, iconName }) => (
  <Animated.View style={[styles.secondaryView, containerStyle]}>
    <TouchableOpacity onPress={onPress} style={styles.secondaryButton}>
      <IconType name={iconName} size={24} color="#FFF" />
    </TouchableOpacity>
  </Animated.View>
);

const AppTabPrimaryButton = ({ containerStyle, onPress, IconType, iconName }) => {
  <View style={[styles.button]}>
  <Animated.View style={containerStyle}>
    <TouchableOpacity activeOpacity={1} onPress={onPress} style={styles.primaryButton}
    >
      <Animated.View>
        <IconType name={iconName} size={24} color="#FFF" />
      </Animated.View>
    </TouchableOpacity>
  </Animated.View>
</View>
};

export const TabAddButton = ({ childButtons }) => {
    /** Other stuff */
    const lockX = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [windowWidth / 2 - 22, windowWidth / 2 - 22 - 60],
  });
  const lockY = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [-20, -75],
  });

  const noteX = mode.interpolate({
    inputRange: [0, 1],
    outputRange: [windowWidth / 2 - 22, windowWidth / 2 - 22 + 60],
  });

  const btnContainerStyles = [
    [styles.secondaryView, { left: lockX, top: lockY,  }],
    [styles.secondaryView, { left: lockX, top: noteY }],
    /** ... */
  ];
  return (
    <Box {...StyleSheet.absoluteFillObject} alignItems="center">
      {childButtons.map(({ iconName, iconType, onPress, isPrimary }, index) => (
        isPrimary ? (<AppTabPrimaryButton /** supply props */ />) :
        (<AppTabSecondaryButton /** supply props */ />)  
      ))}
    </Box>
  );
};

【讨论】:

  • 谢谢。但 AppChildTabButton 的 left 和 top 属性对于每个按钮必须不同。
  • @OğulcanKarayel 我相信它们因位置而异 leftBtn, centerBtn, rigthBtn .. 正确吗?
  • 是的,没错。其中一个是左边,另一个是顶部等
  • 有什么推荐吗?
  • @OğulcanKarayel 你检查过答案了吗?如果我能够提供我所追求的概念,我就不会......
猜你喜欢
  • 1970-01-01
  • 2021-04-07
  • 2018-12-02
  • 2020-01-18
  • 2019-06-04
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多