我可以在React Native中制作动态样式吗?

时间:2015-03-31 08:08:43

标签: css reactjs react-native

假设我有一个像这样的渲染组件:

<View style={jewelStyle}></View>

jewelStyle =

  {
    borderRadius: 10,
    backgroundColor: '#FFEFCC',
    width: 20,
    height: 20,
  },

如何动态和随机分配背景色?我试过了

  {
    borderRadius: 10,
    backgroundColor: getRandomColor(),
    width: 20,
    height: 20,
  },

但是这会使View的所有实例都具有相同的颜色,我希望每个实例都是唯一的。

任何提示?

19 个答案:

答案 0 :(得分:146)

我通常会做一些事情:

<View style={this.jewelStyle()} />

...

jewelStyle = function(options) {
   return {
     borderRadius: 12,
     background: randomColor(),
   }
 }

每次渲染View时,都会使用与之关联的随机颜色实例化新的样式对象。当然,这意味着每次重新渲染组件时颜色都会改变,这可能不是您想要的。相反,你可以这样做:

var myColor = randomColor()
<View style={jewelStyle(myColor)} />

...

jewelStyle = function(myColor) {
   return {
     borderRadius: 10,
     background: myColor,
   }
 }

答案 1 :(得分:53)

是的,您可以并且实际上,您应该使用StyleSheet.create来创建样式。

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

class Header extends Component {
    constructor(props){
        super(props);
    }    

    render() {
        const { title, style } = this.props;
        const { header, text } = defaultStyle;
        const combineStyles = StyleSheet.flatten([header, style]);    

        return (
            <View style={ combineStyles }>
                <Text style={ text }>
                    { title }
                </Text>
            </View>
        );
    }
}    

const defaultStyle = StyleSheet.create({
    header: {
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#fff',
        height: 60,
        paddingTop: 15,
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 3 },
        shadowOpacity: 0.4,
        elevation: 2,
        position: 'relative'
    },
    text: {
        color: '#0d4220',
        fontSize: 16
    }
});    

export default Header;

然后:

<Header title="HOME" style={ {backgroundColor: '#10f1f0'} } />

答案 2 :(得分:18)

如果您仍想利用StyleSheet.create并且还拥有动态样式,请尝试以下方法:

const Circle = ({initial}) => {


const initial = user.pending ? user.email[0] : user.firstName[0];

    const colorStyles = {
        backgroundColor: randomColor()
    };

    return (
        <View style={[styles.circle, colorStyles]}>
            <Text style={styles.text}>{initial.toUpperCase()}</Text>
        </View>
    );
};

const styles = StyleSheet.create({
    circle: {
        height: 40,
        width: 40,
        borderRadius: 30,
        overflow: 'hidden'
    },
    text: {
        fontSize: 12,
        lineHeight: 40,
        color: '#fff',
        textAlign: 'center'
    }
});

请注意style的{​​{1}}属性是如何设置为将样式表与动态样式相结合的数组。

答案 3 :(得分:7)

语法上有一些问题。 这对我有用

<Text style={StyleSheet.flatten([styles.textStyle,{color: 'red'}])}> Hello </Text>

const styles = StyleSheet.create({
   textStyle :{
      textAlign: 'center',   
      fontFamily: 'Arial',
      fontSize: 16
  }
  });

答案 4 :(得分:4)

你会想要这样的东西:

var RandomBgApp = React.createClass({
    render: function() {

        var getRandomColor = function() {
            var letters = '0123456789ABCDEF'.split('');
            var color = '#';
            for (var i = 0; i < 6; i++ ) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            return color;
        };

        var rows = [
            { name: 'row 1'},
            { name: 'row 2'},
            { name: 'row 3'}
        ];

        var rowNodes = rows.map(function(row) {
            return <Text style={{backgroundColor:getRandomColor()}}>{row.name}</Text>
        });

        return (
            <View>
                {rowNodes}
            </View>
        );

    }
});

在这个例子中,我获取rows数组,其中包含组件中行的数据,并将其映射到Text组件数组中。每次创建新的Text组件时,我都会使用内联样式来调用getRandomColor函数。

你的代码的问题是你定义了一次样式,因此getRandomColor只被调用一次 - 当你定义样式时。

答案 5 :(得分:4)

我知道这已经很晚了,但是对于仍然想知道这是一个简单解决方案的人来说。

您可以为样式创建一个数组:

this.state ={
   color: "#fff"
}

style={[
  styles.jewelstyle, {
  backgroundColor: this.state.BGcolor
}

第二个将覆盖样式表中所述的任何原始背景颜色。然后具有更改颜色的功能:

generateNewColor(){
  var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
  this.setState({BGcolor: randomColor})
}

这将生成随机的十六进制颜色。然后只要在任何时候调用该函数,然后重新设置新的背景色即可。

答案 6 :(得分:2)

最简单的是我的:

<TextInput style={styles.default, [
  this.props.singleSourceOfTruth ?
  {backgroundColor: 'black'} : {backgroundColor: 'white'}
]}/>

答案 7 :(得分:1)

我知道有几个答案,但我认为最好也是最简单的是使用状态“改变”是国家目的。

export default class App extends Component {
    constructor(props) {
      super(props);
      this.state = {
          style: {
              backgroundColor: "white"
          }
      };
    }
    onPress = function() {
      this.setState({style: {backgroundColor: "red"}});
    }
    render() {
       return (
          ...
          <View style={this.state.style}></View>
          ...
       )
    }

}

答案 8 :(得分:1)

您可以将状态值直接绑定到样式对象。这是一个例子:

class Timer extends Component{
 constructor(props){
 super(props);
 this.state = {timer: 0, color: '#FF0000'};
 setInterval(() => {
   this.setState({timer: this.state.timer + 1, color: this.state.timer % 2 == 0 ? '#FF0000' : '#0000FF'});
 }, 1000);
}

render(){
 return (
   <View>

    <Text>Timer:</Text>
    <Text style={{backgroundColor: this.state.color}}>{this.state.timer}</Text>
  </View>
 );
 }
}

答案 9 :(得分:1)

我执行以下操作

const colors = {
      white: "#FFFFFF",
      black: "#000000"         
}
<View style={styles(colors).container} />

const styles = ({ white, black }) => StyleSheet.create({

      container: { backgroundColor: darkMode ? black : white }
})

答案 10 :(得分:0)

<View 
 style={[styles.categoryItem,{marginTop: index <= numOfColumns-1 ? 10 : 0   }]}
>                                       

答案 11 :(得分:0)

你可以使用 styled-components for react native 它会为你提供动态样式,就像 web 的情感或 styled-components 一样。

答案 12 :(得分:0)

你可以这样做。

在您的组件中:

const getRandomColor = () => {
  // you can use your component props here.
}

<View style={[styles.jewelStyle, {backgroundColor: getRandomColor()}]} />

使用样式表创建您的样式:

const styles = StyleSheet.create({
  jewelStyle: {
    backgroundColor: 'red',
  },
});

答案 13 :(得分:0)

实际上,您可以将<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit, at?</div> <div class='orig-container'> <div>Lorem ipsum dolor sit amet 1.</div> <div>Lorem ipsum dolor sit amet 2.</div> <div>Lorem ipsum dolor sit amet 3.</div> </div> <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit, at?</div> <div class='target-container'> <div id="auto-mag">Need this text in div this id auto-mag-id</div> <div id="karat">Need this text in div this id karat-id</div> <div id="zebra">Need this text in div this id zebra-id</div> </div>对象写为具有函数值的键,它可以正常工作,但是在TypeScript中存在类型问题:

StyleSheet.create

答案 14 :(得分:0)

这对我有用:

render() {
  const { styleValue } = this.props;
  const dynamicStyleUpdatedFromProps = {
    height: styleValue,
    width: styleValue,
    borderRadius: styleValue,
  }

  return (
    <View style={{ ...styles.staticStyleCreatedFromStyleSheet, ...dynamicStyleUpdatedFromProps }} />
  );
}

由于某种原因,这是我的正确更新的唯一方法。

答案 15 :(得分:0)

万一有人需要申请条件

 selectedMenuUI = function(value) {
       if(value==this.state.selectedMenu){
           return {
                flexDirection: 'row',
                alignItems: 'center',
                paddingHorizontal: 20,
                paddingVertical: 10,
                backgroundColor: 'rgba(255,255,255,0.3)', 
                borderRadius: 5
           }  
       } 
       return {
            flexDirection: 'row',
            alignItems: 'center',
            paddingHorizontal: 20,
            paddingVertical: 10
       }
    }

答案 16 :(得分:0)

使用对象传播运算符“ ...”为我工作:

<View style={{...jewelStyle, ...{'backgroundColor': getRandomColor()}}}></View>

答案 17 :(得分:0)

是的,您可以制作动态样式。您可以从组件传递值。

首先创建StyleSheetFactory.js

import { StyleSheet } from "react-native";
export default class StyleSheetFactory {
  static getSheet(backColor) {
    return StyleSheet.create({
      jewelStyle: {
        borderRadius: 10,
        backgroundColor: backColor,
        width: 20,
        height: 20,
      }
    })
  }
}

然后按照以下方式在您的组件中使用

import React from "react";
import { View } from "react-native";
import StyleSheetFactory from './StyleSheetFactory'
class Main extends React.Component {
  getRandomColor = () => {
    var letters = "0123456789ABCDEF";
    var color = "#";
    for (var i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  };

  render() {
    return (
      <View>
        <View
          style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
        />
        <View
          style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
        />
        <View
          style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
        />
      </View>
    );
  }
}

答案 18 :(得分:0)

如果您使用的是带过滤器的屏幕,并且您想要设置过滤器的背景,无论其是否被选中,您可以执行以下操作:

<TouchableOpacity style={this.props.venueFilters.includes('Bar')?styles.filterBtnActive:styles.filterBtn} onPress={()=>this.setFilter('Bar')}>
<Text numberOfLines={1}>
Bar
</Text>
</TouchableOpacity>

在哪个集合过滤器上:

setVenueFilter(filter){
  var filters = this.props.venueFilters;
  filters.push(filter);
  console.log(filters.includes('Bar'), "Inclui Bar");
  this.setState(previousState => {
    return { updateFilter: !previousState.updateFilter };
  });
  this.props.setVenueFilter(filters);
}

PS:函数this.props.setVenueFilter(filters)是一个redux动作,this.props.venueFilters是一个redux状态。