我可以在反应本机动态样式?

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

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

在哪里

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

我怎样才能使背景颜色动态和随机分配? 我试过了吗

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

但是这使得所有的视图实例都有相同的颜色,我希望每一个都是独一无二的。

有什么建议吗?

207526 次浏览

我通常会这样做:

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

...

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

每次呈现“视图”时,都会用与其关联的随机颜色实例化一个新样式对象。当然,这意味着每次重新呈现组件时颜色都会改变,这可能不是您想要的。相反,你可以这样做:

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

...

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

你会想要这样的东西:

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>
);


}
});

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

代码的问题在于您只定义了一次样式,因此在定义样式时,getRRandom Color 只被调用了一次。

是的,你可以,实际上,你应该使用 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'} } />

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

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>
...
)
}

}

您可以将状态值直接绑定到样式对象:

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>
);
}
}

如果你仍然想利用 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'
}
});

请注意,Viewstyle属性是如何设置为一个数组的,该数组将样式表与动态样式组合在一起。

在句法上有点问题。 这招对我很管用

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


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

最简单的是我的:

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

例如,如果您正在使用带有过滤器的屏幕,并且您想设置过滤器的背景,以确定它是否被选中,您可以这样做:

<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)是一个还原动作,而 this.props.venueFilters是一个还原状态。

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

首先创建 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>
);
}
}

使用对象扩展运算符“ ...”对我很有效:

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

以防有人需要附加条件

 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
}
}

以下是对我有效的方法:

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


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

出于某种原因,这是唯一的方式,我的将更新正确。

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

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

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})
}

这将生成一个随机的十六进制颜色。然后随时调用该函数,砰,新的背景颜色。

实际上,你可以把 StyleSheet.create对象写成带有函数值的键,它可以正常工作,但是在 TypeScript 中有一个类型问题:

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


const SomeComponent = ({ bgColor }) => (
<View style={styles.wrapper(bgColor)}>
<Text style={styles.text}>3333</Text>
</View>
);


const styles = StyleSheet.create({
wrapper: color => ({
flex: 1,
backgroundColor: color,
}),
text: {
color: 'red',
},
});


你可以这么做。

在您的组件中:

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


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

使用样式表创建样式:

const styles = StyleSheet.create({
jewelStyle: {
backgroundColor: 'red',
},
});
  import React, { useContext, useMemo } from 'react';
import { Text, StyleSheet, View } from 'react-native';
import colors from '../utils/colors';
import ThemeContext from './../contexts/ThemeContext';


export default (props) => {
const { theme } = useContext(ThemeContext);


// Constructing styles for current theme
const styles = useMemo(() => createStyles(theme), [theme]);


return (
<View style={styles.container}>
<Text style={styles.label}>{label}</Text>
</View>
);
};


const createStyles = (theme: AppTheme) =>
StyleSheet.create({
container: { width: '100%', position: 'relative', backgroundColor: colors[theme].background },
label: {
fontSize: 13,
fontWeight: 'bold',
},
});

颜色

export type AppTheme = 'dark' | 'light';


const light: Colors = {
background: '#FFFFFF',
onBackground: '#333333',
gray: '#999999',
grayLight: '#DDDDDD',
red: 'red',
};


const dark: Colors = {
background: '#333333',
onBackground: '#EEEEEE',
gray: '#999999',
grayLight: '#DDDDDD',
red: 'red',
};


const colors = {
dark,
light,
primary: '#2E9767',
secondary: '#F6D130',
};


export default colors;

你可以使用样式组件的反应本地它将为您提供动态样式就像情感或样式组件的网页。

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

如果您遵循的是反应原生函数方法,那么您可以使用一个名为 dynamic-styles的包来尝试正确地解决您的问题。

// -- theme.js ------------------------------------------------------


// Initialization of a StyleSheet instance called 'styleSheet'
export const styleSheet = createStyleSheet({
theme: /* optional theme */
});






// -- MyComponent.js -----------------------------------------------


// Create dynamic stylesheet that has access
// to the previously specified theme and parameters
const useStyles = styleSheet.create(({theme, params}) => ({
root: /* Dynamic Styles */,
button: /* Dynamic Styles */,
text: /* Dynamic Styles */,
}));


const MyComponent = (props) => {
// Access dynamic styles using the created 'useStyles()' hook
// and specify the corresponding parameters
const { styles } = useStyles({ color: props.color, fontSize: 10 });
    

return (
<div className={styles.root}>
{/* */}
</div>
);
}

它基本上允许您创建 dynamic样式表 并使用 React hook模式将它们链接到功能组件。

- > Codesandbox

对于一些相对简单的事情,你可以使用这种方法:

StyleSheet.create({
item: props.selectedId === item.id ? {
backgroundColor: 'red',
}: null
});