首页 > 解决方案 > 如何在设备方向更改时更新主题

问题描述

我正在尝试使用钩子实现方向更改。我从 app.tsx 调用了方向挂钩,我想更新使用 widthPercentageToDP() 函数的所有内容(主题、组件中的样式)。我怎样才能做到这一点。我想不通。

使用方向.tsx

export let { width, height } = Dimensions.get("window");

const heightPercentageToDP = (heightPercent: string | number): number => {
  // Parse string percentage input and convert it to number.
  const elemHeight =
    typeof heightPercent === "number"
      ? heightPercent
      : parseFloat(heightPercent);

  // Use PixelRatio.roundToNearestPixel method in order to round the layout
  // size (dp) to the nearest one that correspons to an integer number of pixels.
  return PixelRatio.roundToNearestPixel((height * elemHeight) / 100);
};

export const useScreenDimensions = () => {
  const [screenData, setScreenData] = useState({});

  useEffect(() => {
    setScreenData({orientation:currentOrientation()});

    Dimensions.addEventListener("change", (newDimensions) => {
     
      width = newDimensions.screen.width;
      height = newDimensions.screen.height;
      setScreenData({orientation:currentOrientation()}); // can be used with this height and width

      //console.log(newDimensions.window);
    });

    return () => Dimensions.removeEventListener("change", () => {});
  });

  return {
    
    width,height,
    screenData
  };
};

主题文件

const theme = {
  
    spacing: {
      m:widthPercentageToDP("2%") // it must be updated when orientation changes.
    },
    borderRadii: {
     s:widthPercentageToDP("5%") // it must be updated when orientation changes. 
    },
    textVariants: {
     body:{
       fontSize:widthPercentageToDP("%3"),
       
     }
    },
 
  };

应用程序.tsx

 const {screenData} = useScreenDimensions();
 console.log(screenData)
  
 return (
    <ThemeProvider>
      <LoadAssets {...{ fonts, assets }}>
       <Example/>
      </LoadAssets>
    </ThemeProvider>
  );
}

例子.tsx

export const Example = ({}) => {

     
        return (
            <Box>
                <Text variant="body">hey</Text>

                {/* // it must be updated when orientation changes. */}
                <View style={{width:widthPercentageToDP("40%")}}/> 
                
            </Box>
        );
}

框和主题来自 theme.tsx 文件。文本组件接受在 theme.tsx 中定义的变体道具

标签: react-nativethemesdevice-orientation

解决方案


使用react-native-orientation你可以做你想做的事,然后设备方向会改变。

例子:

import Orientation from 'react-native-orientation';

export default class AppScreen extends Component {

  componentWillMount() {
    const initial = Orientation.getInitialOrientation();
    if (initial === 'PORTRAIT') {
      // do something
    } else {
      // do something else
    }
  },

  componentDidMount() {
    // this will listen for changes
    Orientation.addOrientationListener(this._orientationDidChange);
  },

  _orientationDidChange = (orientation) => {
    if (orientation === 'LANDSCAPE') {
      // do something with landscape layout
    } else {
      // do something with portrait layout
    }
  },

  componentWillUnmount() {

    // Remember to remove listener to prevent memory leaks
    Orientation.removeOrientationListener(this._orientationDidChange);
  }

推荐阅读