返回

Android升级TargetSdk33后 ReactNative文本被遮挡问题详解

Android

Android TargetSDK 升级到 33 后 React Native Text 问题的分析与解决方案

随着 Android 系统的不断更新,React Native 也在不断升级以支持新版本。在 Android targetSDK 升级到 33 后,一些 React Native 的 Text (重点是自定义字体 FontFamily 后)会出现高度计算不正确和被遮挡的问题。本文将详细分析该问题并提供解决方案。

问题分析

高度计算不正确

在 Android targetSDK 升级到 33 后,React Native 的 Text 高度计算会受到影响,导致高度计算不正确。这主要是由于 Android 13 引入了一个新的 API:android.view.ViewTreeObserver.OnPreDrawListener。该 API 允许应用程序在视图绘制之前执行一些操作。在 React Native 中,OnPreDrawListener 用于计算 Text 的高度。然而,在 Android 13 中,OnPreDrawListener 的行为发生了变化。它现在会在视图绘制完成后才执行,这导致 Text 的高度无法正确计算。

文本被遮挡

除了高度计算不正确之外,React Native 的 Text 还可能会出现被遮挡的问题。这主要是由于 Android 13 中对字体渲染机制的更改。在 Android 13 中,字体渲染引擎从 FreeType 切换到 Skia。这种切换导致一些字体的渲染结果发生了变化,导致文本可能被遮挡。

解决方案

高度计算不正确

为了解决高度计算不正确的问
题,React Native 团队提供了一个解决方案。该解决方案是在 Text 组件中添加一个新的属性:onPreDrawonPreDraw 属性是一个回调函数,它会在视图绘制之前执行。在回调函数中,我们可以手动计算 Text 的高度并将其设置为 Text 组件的高度。

代码示例:

import React, { useEffect, useRef } from 'react';
import { Text } from 'react-native';

const MyText = (props) => {
  const textRef = useRef(null);

  useEffect(() => {
    const textHeight = textRef.current.getBoundingClientRect().height;
    props.onLayout({ nativeEvent: { layout: { height: textHeight } } });
  }, []);

  return (
    <Text ref={textRef} {...props} />
  );
};

文本被遮挡

为了解决文本被遮挡的问题,我们可以使用 Android 13 提供的新 API:android.graphics.fonts.FontVariationAxisFontVariationAxis API 允许我们指定字体的变体轴,从而改变字体的渲染结果。我们可以使用 FontVariationAxis API 来调整字体的大小和粗细,直到文本不再被遮挡。

代码示例:

import android.graphics.fonts.FontVariationAxis;
import android.graphics.Typeface;

Typeface typeface = Typeface.create("Roboto", Typeface.NORMAL);
float weightVariation = new FontVariationAxis("wght", 500);
typeface = Typeface.create(typeface, new FontVariationAxis[] { weightVariation });

总结

以上就是 Android targetSDK 升级到 33 后 React Native 的 Text 出现高度计算不正确和被遮挡问题的分析和解决方案。希望本文能够帮助大家解决这个问题。

常见问题解答

  1. 为什么会出现高度计算不正确和文本被遮挡的问题?
    • 高度计算不正确是由于 Android 13 中 OnPreDrawListener API 的行为变化。文本被遮挡是由于字体渲染引擎从 FreeType 切换到 Skia 引起的。
  2. 如何解决高度计算不正确的问题?
    • 在 Text 组件中使用 onPreDraw 属性手动计算高度。
  3. 如何解决文本被遮挡的问题?
    • 使用 FontVariationAxis API 调整字体的变体轴。
  4. 这些解决方案是否适用于所有自定义字体?
    • 是的,这些解决方案适用于所有自定义字体。
  5. 这些解决方案是否会影响性能?
    • 这些解决方案可能会对性能产生轻微影响,但通常是不可察觉的。