Native base Footer 在 react native 中接受玩家的触摸

Native base Footer accepting touches for player in react native

我有一个 MainFooter 组件,其中包含页脚和迷你播放器,单击时可以动画显示全视图。我有一个问题,每当我们点击其中一个页脚选项卡时,播放器会最大化,然后卡在那里,没有反应。

此外,点击播放器中的向下箭头图标不会将其最小化,点击 MiniPlayer 也不会将其最大化,但我们可以通过单击并拖动它到全视图来最大化 MiniPlayer,最大化播放器也是如此。

这是 MainFooter 组件:

export const MainFooter = ({ setCounter, counter }: Props) => {
  const translationY = new Value(0);
  const velocityY = new Value(0);
  const state = new Value(State.UNDETERMINED);
  const offset = new Value(SNAP_BOTTOM);
  const goUp: Animated.Value<0 | 1> = new Value(0);
  const goDown: Animated.Value<0 | 1> = new Value(0);

  const gestureHandler = onGestureEvent({
    state,
    translationY,
    velocityY,
  });

  const translateY = clamp(
    withSpring({
      state,
      value: translationY,
      velocity: velocityY,
      snapPoints: [SNAP_TOP, SNAP_BOTTOM],
      config,
    }),
    SNAP_TOP,
    SNAP_BOTTOM
  );

  const translateY_ = withSpring({
    value: clamp(translationY, SNAP_TOP, SNAP_BOTTOM),
    velocity: velocityY,
    offset,
    state,
    snapPoints: [SNAP_TOP, SNAP_BOTTOM],
    config,
  });

  const translateBottomTab = interpolate(translateY, {
    inputRange: [SNAP_BOTTOM - TABBAR_HEIGHT, SNAP_BOTTOM],
    outputRange: [TABBAR_HEIGHT, 0],
    extrapolate: Extrapolate.CLAMP,
  });

  const opacity = interpolate(translateY, {
    inputRange: [SNAP_BOTTOM - MINIMIZED_PLAYER_HEIGHT, SNAP_BOTTOM],
    outputRange: [0, 1],
    extrapolate: Extrapolate.CLAMP,
  });

  const opacity2 = interpolate(translateY, {
    inputRange: [
      SNAP_BOTTOM - MINIMIZED_PLAYER_HEIGHT * 2,
      SNAP_BOTTOM - MINIMIZED_PLAYER_HEIGHT,
    ],
    outputRange: [0, 1],
    extrapolate: Extrapolate.CLAMP,
  });

  return (
    <>
      <PanGestureHandler {...gestureHandler}>
        <Animated.View
          style={[
            styles.playerSheet,
            { transform: [{ translateY: translateY }] },
          ]}
        >
          <Player
            onPress={() => {
              goDown.setValue(1);
              console.log('player pressed!');
            }}
          />
          <Animated.View
            pointerEvents='none'
            style={{
              opacity: opacity2,
              backgroundColor: '#e0e0e0',
              ...StyleSheet.absoluteFillObject,
            }}
          />
          <Animated.View
            style={{
              opacity,
              position: 'absolute',
              top: 0,
              left: 0,
              right: 0,
              height: MINIMIZED_PLAYER_HEIGHT,
            }}
          >
            <MiniPlayer
              onPress={() => {
                console.log('mini player pressed!');
                goUp.setValue(1);
              }}
            />
          </Animated.View>
        </Animated.View>
      </PanGestureHandler>
      <Animated.View
        style={{ transform: [{ translateY: translateBottomTab }] }}
      >
        <FooterTabsContainer counter={counter} setCounter={setCounter} />
      </Animated.View>
    </>
  );
};

const styles = StyleSheet.create({
  playerSheet: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: '#e0e0e0',
  },
  container: {
    // backgroundColor: '#e0e0e0',
    // position: 'absolute',
    // bottom: 0,
    // left: 0,
    // right: 0,
    // height: TABBAR_HEIGHT,
    // flexDirection: 'row',
    // borderTopColor: 'black',
    // borderWidth: 1,
    height: 'auto',
  },
});

这里是 FooterTabsContainer 组件:

const FooterTabsContainer = ({ counter, setCounter }: Props) => {
  const tintColor = {
    homeIcon: counter === 0 ? '#FFBC00' : '#555',
    playIcon: counter === 1 ? '#FFBC00' : '#555',
    loveIcon: counter === 2 ? '#FFBC00' : '#555',
    profileIcon: counter === 3 ? '#FFBC00' : '#555',
  };
  return (
    <>
      <Footer>
        <FooterTab style={styles.footerTab}>
          <Button onPress={() => setCounter(0)}>
            <Image
              source={homeIcon}
              style={{ ...styles.footerIcon, tintColor: tintColor.homeIcon }}
            />
          </Button>
          <Button onPress={() => setCounter(1)}>
            <Image
              source={playIcon}
              style={{ ...styles.footerIcon, tintColor: tintColor.playIcon }}
            />
          </Button>
          <Button onPress={() => setCounter(2)}>
            <Image
              source={loveIcon}
              style={{ ...styles.footerIcon, tintColor: tintColor.loveIcon }}
            />
          </Button>
          <Button
            onPress={() => {
              setCounter(3);
              console.log('profile icon clicked!');
            }}
          >
            <Image
              source={profileIcon}
              style={{ ...styles.footerIcon, tintColor: tintColor.profileIcon }}
            />
          </Button>
        </FooterTab>
      </Footer>
    </>
  );
};

export default FooterTabsContainer;

const styles = StyleSheet.create({
  footerTab: {
    backgroundColor: '#FFF',
    borderWidth: 2,
    borderColor: '#f0f0f0',
  },
  footerIcon: {
    width: 25,
    height: 25,
  },
});

我将不胜感激任何关于为什么会发生这种情况的帮助或意见:

  1. 解决了单击任何页脚选项卡时使 MiniPlayer 最大化的问题。
  2. 修复了 MiniPlayer 在点击时没有最大化和全屏播放器在点击向下箭头图标时没有最小化的问题

我正在使用 "react-native-reanimated": "^1.13.2""react-native-redash": "^8.0.0""native-base": "^2.15.2""react": "16.13.1", "react-native": "^0.64.0","react-native-gesture-handler": "^1.9.0"

Maximized Player

Miniplayer:

这是因为将动画值存储为新值,所以无论何时;迁移到另一个页脚选项卡,状态因重新渲染而丢失,播放器返回到其原始状态(向上)。要在 useRef() 内修复此环绕动画值,然后使用它们:

  const translationY = useRef(new Value(0));
  const velocityY = useRef(new Value(0));
  const state = useRef(new Value(State.UNDETERMINED));
  const offset = new Value(SNAP_BOTTOM);
  const goUp: React.MutableRefObject<Animated.Value<0 | 1>> = useRef(
    new Value(0)
  );
  const goDown: React.MutableRefObject<Animated.Value<0 | 1>> = useRef(
    new Value(0)
  );
  .
  .
  .
  const translateY = useRef(
    clamp(
      withSpring({
        state: state.current,
        value: translationY.current,
        velocity: velocityY.current,
        offset,
        snapPoints: [SNAP_TOP, SNAP_BOTTOM],
        config,
      }),
      SNAP_TOP,
      SNAP_BOTTOM
    )
  );