You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何实现开关隐藏页面控件仅显示MJPEG摄像头背景流

实现方案

你只需要新增一个控制显隐的状态,给需要隐藏的控件加上条件判断即可,修改后的完整代码如下:

import { Layout } from "components/common";
import { Box, Text, Icon, IconButton, VStack, Button } from "native-base";
import React, {
  useCallback,
  useLayoutEffect,
  useState,
} from "react";
import * as ScreenOrientation from "expo-screen-orientation";
import { useFocusEffect, useNavigation } from "@react-navigation/core";
import { Feather } from "@expo/vector-icons";
import { KorolJoystick, KorolSlider, Stepper } from "components/ui";
import { SettingsModal } from "components/CameraView";
import { WebView } from "react-native-webview";
import { useAppSelector } from "redux-store/store";

const ip = "10.42.0.1";
const ws = new WebSocket(`ws://${ip}:2100/ws`);
ws.onopen = () => {
  console.log("connection established");
};

const CameraView = () => {
  const nav = useNavigation();
  const [showSettings, setShowSettings] = useState(false);
  const [hideControls, setHideControls] = useState(false); // 新增控制显隐的状态
  const { controlType, step } = useAppSelector((state) => state.cameraSettings);
  const [x, setX] = useState(0);

  useLayoutEffect(() => {
    ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
  }, []);

  useFocusEffect(
    useCallback(() => {
      return () => {
        ScreenOrientation.unlockAsync();
      };
    }, [])
  );

  return (
    <Layout>
      <Box flex={1} position="relative">
        {/* MJPEG视频流始终显示 */}
        <WebView
          originWhitelist={["*"]}
          scrollEnabled={false}
          scalesPageToFit
          style={{
            backgroundColor: "transparent",
          }}
          containerStyle={{
            flex: 1,
          }}
          source={{
            uri: "http://10.42.0.1:2101/mjpeg",
          }}
        />

        {/* 显隐切换按钮 - 始终显示 */}
        <IconButton
          position="absolute"
          top="5"
          right="5"
          icon={<Icon as={Feather} color="primary.500" name={hideControls ? "eye" : "eye-off"} />}
          colorScheme="primary"
          onPress={() => setHideControls(prev => !prev)}
        />

        {/* 以下所有控件仅在hideControls为false时显示 */}
        {!hideControls && (
          <>
            <VStack
              position="absolute"
              display="flex"
              width="full"
              flexDirection="row"
              padding="5"
              alignItems="center"
            >
              <IconButton
                marginRight="auto"
                icon={<Icon as={Feather} color="primary.500" name="arrow-left" />}
                colorScheme="primary"
                onPress={() => nav.goBack()}
              />
              <Button
                size="md"
                startIcon={<Icon size="xs" as={Feather} name="plus" />}
                backgroundColor="primary.500:alpha.40"
              >
                Add Waypoint
              </Button>
              <IconButton
                icon={<Icon as={Feather} color="primary.500" name="settings" />}
                colorScheme="primary"
                onPress={() => setShowSettings(true)}
                marginRight="12" // 给右侧的显隐开关留出位置
              />
            </VStack>

            <VStack position="absolute" bottom="30" left="30" width="56" space={2}>
              <VStack>
                <Text>Slide</Text>
                <KorolSlider
                  value={x}
                  onChange={(slider) => {
                    setX(slider);
                    console.log(slider);
                  }}
                  onDragEnd={() => {
                    const message = {
                      from: "FromClient",
                      data: {
                        case: "joystick",
                        joystick: {
                          slider: x,
                        },
                      },
                    };
                    ws.send(JSON.stringify(message));
                  }}
                />
              </VStack>
            </VStack>

            <Box position="absolute" right="30" bottom="30">
              {controlType === "joystick" ? (
                <KorolJoystick
                  onMove={(values) => {
                    console.log(values);
                    const message = {
                      from: "FromClient",
                      data: {
                        case: "joystick",
                        joystick: {
                          angle: values.angle.radian,
                          force: values.force,
                        },
                      },
                    };
                    ws.send(JSON.stringify(message));
                  }}
                  onStop={(values) => {
                    const message = {
                      from: "FromClient",
                      data: {
                        case: "joystick",
                        joystick: {
                          angle: 0,
                          force: 0,
                        },
                      },
                    };
                    ws.send(JSON.stringify(message));
                  }}
                />
              ) : (
                <Stepper
                  onPress={(dir) => {
                    const vel = 5;
                    let message;
                    if (dir === "up") {
                      message = {
                        from: "FromClient",
                        data: {
                          case: "controlCMDRel",
                          moveData: { tilt: [step, vel] },
                        },
                      };
                    }
                    if (dir === "down") {
                      message = {
                        from: "FromClient",
                        data: {
                          case: "controlCMDRel",
                          moveData: { tilt: [-step, vel] },
                        },
                      };
                    }
                    if (dir === "left") {
                      message = {
                        from: "FromClient",
                        data: {
                          case: "controlCMDRel",
                          moveData: { pan: [-step, vel] },
                        },
                      };
                    }
                    if (dir === "right") {
                      message = {
                        from: "FromClient",
                        data: {
                          case: "controlCMDRel",
                          moveData: { pan: [step, vel] },
                        },
                      };
                    }
                    if (message) ws.send(JSON.stringify(message));
                  }}
                />
              )}
            </Box>
          </>
        )}
      </Box>
      <SettingsModal
        show={showSettings}
        onClose={() => setShowSettings(false)}
      />
    </Layout>
  );
};

export default CameraView;

内容的提问来源于stack exchange,提问作者Matthew Mukherjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:06:06