使用到的第三方库是react-native-svg,

image.png
代码如下:
import React, { useMemo, useState } from "react";
import { StyleSheet, Text as RNText, View } from "react-native";
import Svg, { Defs, LinearGradient, Stop, Text, Use } from "react-native-svg";
import { FontFamily } from "../../../constants";
const getFallbackWidth = (text, fontSize) => {
const value = `${text ?? ""}`;
let width = 0;
value.split("").forEach((char) => {
if (char === " ") {
width += fontSize * 0.32;
} else if (/[\u4e00-\u9fa5]/.test(char)) {
width += fontSize;
} else {
width += fontSize * 0.58;
}
});
return Math.max(1, Math.ceil(width));
};
/**
* 渐变文字(根据文本适应宽度)
*/
export default function LinearGradientText({
text,
color01 = "#FEAE5C",
color02 = "#FEF97B",
color03 = "#FFFEAD",
fontSize = 36,
lineHeight = 44,
}) {
const fallbackWidth = useMemo(() => getFallbackWidth(text, fontSize), [fontSize, text]);
const [measuredWidth, setMeasuredWidth] = useState(0);
const width = measuredWidth || fallbackWidth;
const textStyle = useMemo(() => ({
fontFamily: FontFamily.ExtraBold,
fontSize,
fontWeight: "800",
lineHeight,
}), [fontSize, lineHeight]);
return <View style={{ width, height: lineHeight }}>
<RNText
numberOfLines={1}
onLayout={({ nativeEvent }) => {
const nextWidth = Math.ceil(nativeEvent.layout.width);
if (nextWidth > 0 && nextWidth !== measuredWidth) {
setMeasuredWidth(nextWidth);
}
}}
style={[styles.measureText, textStyle]}>
{text}
</RNText>
<Svg width={width} height={lineHeight} viewBox={`0 0 ${width} ${lineHeight}`}>
<Defs>
<LinearGradient
id="Gradient"
gradientUnits="userSpaceOnUse"
x1="0"
y1={lineHeight}
x2={width}
y2="0">
<Stop offset="0.02" stopColor={color01} />
<Stop offset="0.4" stopColor={color02} />
<Stop offset="1" stopColor={color03} />
</LinearGradient>
<Text
id="Text"
x="0"
y={fontSize}
fontSize={fontSize}
textAnchor="start"
fontFamily={FontFamily.ExtraBold}
fontWeight={"800"}>
{text}
</Text>
</Defs>
<Use href="#Text" fill="url(#Gradient)" />
</Svg>
</View>
}
const styles = StyleSheet.create({
measureText: {
left: 0,
opacity: 0,
position: "absolute",
top: 0,
},
});