React Native - 根据背景颜色改变文本颜色

3
我希望能够实现以下图片所示的功能,但我不知道如何达到这个目的(我在Google上搜索了一下,但只找到了原生代码Swift、Obj C等的结果)。
enter image description here
我需要对一些层进行处理或类似的操作吗?
感谢您的回答!
维克托
3个回答

4

嗨,非常感谢你的回答,

我需要使用省略号来处理文本溢出,按照您提供的方法实现比较复杂,因此我使用了maskView。

具体的实现方式如下:

// container
<View style={{flex:1, borderRadius: 200, height: 25, overflow:hidden}}>

    // Progress bar support
    <View style={{flex:1, backgroundColor: 'gray'}} />

    // Progress bar, I play with "width" to indicate percentage
    <View style={[StyleSheet.absoluteFill, {width: "50%", backgroundColor: 'green'}]} />
    <MaskedView
        style={[StyleSheet.absoluteFill, {justifyContent: 'center'}]}
        maskElement={
            // I define text which will be masked
            <View style={[StyleSheet.absoluteFill, {justifyContent: 'center'}]}>
                <Text
                    style={{marginHorizontal: 15, fontSize: 13}}
                    numberOfLines={1}>
                    Text color change
                </Text>
            </View>
        }>

        // I define a default mask that I apply to the text so that it is 'black' when it is not ON the progress bar.
        <View style={[StyleSheet.absoluteFill,{backgroundColor: 'black'}]} />

        // I define the mask that takes the size of the progress bar and that I apply over the default mask (to overwrite it) so that the text under the mask becomes white.
        <View style={[StyleSheet.absoluteFill,{width:"50%", backgroundColor: '#fff'}]} />
    </MaskedView>
</View>

所以我有一个默认的进度条表示“最大进度”,然后我定义我的进度条(根据百分比增长或缩小)。然后,我使用文本作为MaskedElement定义了一个MaskedView。默认情况下,在文本上应用黑色掩码,使其始终是黑色的,无论发生什么。然后,我用与我的进度条完全相同大小的白色掩码覆盖了这个掩码。因此,进度条掩码下方的所有内容都变成了白色,以适应我的“暗色”进度条,而其余部分则为黑色!这样,我就可以很容易地通过ellpsizeMode="tail"来管理文本溢出。这就是结果:

result1

result 2


2

与之前的答案相同的样式,但是通过添加另一个视图来改变实现方式,该视图包含不同背景颜色和文本颜色的相同文本,位于灰色视图内,位置为'absolute'

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

export default class Example extends React.Component {
  state = {
    text: 'Text color changes',
  };

  render() {
    console.log(this.state.textArray);
    return (
      <View style={styles.container}>
        <View
          style={{
            flex: 1,
            backgroundColor: '#d0d3d6',
            borderTopRightRadius: 20,
            borderBottomRightRadius: 20,
            borderTopLeftRadius: 20,
            borderBottomLeftRadius: 20,
            overflow: 'hidden',
          }}>
          <Text style={styles.leftLabelStyle}>{this.state.text}</Text>
          <View
            style={{
              width: '30%',
              height: '100%',
              position: 'absolute',
              backgroundColor: '#5483b3',
            }}>
            <Text numberOfLines={1} ellipsizeMode='clip' 
              {styles.RightLabelStyle}>
              {this.state.text}
            </Text>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    marginHorizontal: 20,
  },

  leftLabelStyle: {
    fontSize: 16,
    paddingVertical: 5,
    color: '#000',
  },
  RightLabelStyle: {
    fontSize: 16,
    paddingVertical: 5,
    color: '#fff',
  },
});

在“Snack”上的示例:https://snack.expo.io/@hassan190011/loading

编辑:在numberOfLines之后添加ellipsizeMode='clip'以删除省略号。


0

这个实现有一点不同,主要是我有两个不同的视图,分别具有不同的样式,最后使用主视图来包装这两个视图。

import * as React from "react";
import { Text, View, StyleSheet } from "react-native";

export default class Example extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.leftViewStyle}>
          <Text style={styles.leftLabelStyle}>Text color ch</Text>
        </View>
        <View style={styles.rightViewStyle}>
          <Text style={styles.rigthLabelStyle}>ange</Text>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    marginHorizontal: 20
  },
  leftViewStyle: {
    flex: 1,
    backgroundColor: "#5483b3",
    alignItems: "flex-end",
    borderTopLeftRadius: 20,
    borderBottomLeftRadius: 20
  },
  rightViewStyle: {
    flex: 1,
    backgroundColor: "#d0d3d6",
    borderTopRightRadius: 20,
    borderBottomRightRadius: 20
  },
  leftLabelStyle: {
    fontSize: 16,
    paddingVertical: 5,
    color: "#fff"
  },
  rigthLabelStyle: {
    fontSize: 16,
    paddingVertical: 5,
    color: "#000"
  }
});

这可能不是最优解决方案。如果您有任何疑问,请随时提出。 希望这能帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接