Angenommen, ich habe eine Komponente mit einem Rendering wie folgt:
<View style={jewelStyle}></View>
Wo JewelStyle =
{
borderRadius: 10,
backgroundColor: '#FFEFCC',
width: 20,
height: 20,
},
Wie kann ich die Hintergrundfarbe dynamisieren und zufällig zuweisen? ich habe es versucht
{
borderRadius: 10,
backgroundColor: getRandomColor(),
width: 20,
height: 20,
},
Dies hat jedoch zur Folge, dass alle Instanzen von View dieselbe Farbe haben. Ich möchte, dass jede einzelne Person angezeigt wird.
Irgendwelche Tipps?
Normalerweise mache ich etwas in der Art von:
<View style={this.jewelStyle()} />
...
jewelStyle = function(options) {
return {
borderRadius: 12,
background: randomColor(),
}
}
Bei jedem Rendern von View wird ein neues Stilobjekt mit einer zufälligen Farbe instanziiert. Dies bedeutet natürlich, dass sich die Farben jedes Mal ändern, wenn die Komponente erneut gerendert wird. Dies ist möglicherweise nicht das, was Sie möchten. Stattdessen könnten Sie so etwas tun:
var myColor = randomColor()
<View style={jewelStyle(myColor)} />
...
jewelStyle = function(myColor) {
return {
borderRadius: 10,
background: myColor,
}
}
Ja, Sie können und tatsächlich sollten Sie StyleSheet.create
verwenden, um Ihre Stile zu erstellen.
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;
Und dann:
<Header title="HOME" style={ {backgroundColor: '#10f1f0'} } />
Wenn Sie dennoch StyleSheet.create
nutzen möchten und dynamische Stile verwenden möchten, probieren Sie Folgendes aus:
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'
}
});
Beachten Sie, dass die style
-Eigenschaft der View
als Array festgelegt ist, das Ihr Stylesheet mit Ihren dynamischen Stilen kombiniert.
Hatte einige Probleme syntaktisch ... Das hat für mich funktioniert
<Text style={StyleSheet.flatten([styles.textStyle,{color: 'red'}])}> Hello </Text>
const styles = StyleSheet.create({
textStyle :{
textAlign: 'center',
fontFamily: 'Arial',
fontSize: 16
}
});
Sie wollen so etwas wie:
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>
);
}
});
In diesem Beispiel nehme ich das Zeilenarray, das die Daten für die Zeilen in der Komponente enthält, und ordne sie einem Array von Textkomponenten zu. Ich benutze Inline-Stile, um die Funktion getRandomColor
jedes Mal aufzurufen, wenn ich eine neue Textkomponente erstelle.
Das Problem bei Ihrem Code ist, dass Sie den Stil einmal definieren. Daher wird getRandomColor nur einmal aufgerufen, wenn Sie den Stil definieren.
Das einfachste ist meins:
<TextInput style={styles.default, [
this.props.singleSourceOfTruth ?
{backgroundColor: 'black'} : {backgroundColor: 'white'}
]}/>
Ich weiß, dass es mehrere Antworten gibt, aber ich denke, der beste und einfachste ist die Verwendung eines Zustands "Ändern" ist der Zweck des Staates.
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>
...
)
}
}
Ja, Sie können dynamische Stile erstellen. Sie können Werte von Komponenten übergeben.
Erstellen Sie zuerst 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,
}
})
}
}
dann verwenden Sie es in Ihrer Komponente auf folgende Weise
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>
);
}
}
Sie können den Statuswert direkt an das Style-Objekt binden. Hier ist ein Beispiel:
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>
);
}
}
Für den Fall, dass jemand Bedingungen anwenden muss
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
}
}
Die Verwendung des Objekt-Spread-Operators "..." hat für mich funktioniert:
<View style={{...jewelStyle, ...{'backgroundColor': getRandomColor()}}}></View>
Wenn Sie beispielsweise einen Bildschirm mit Filtern verwenden und den Hintergrund des Filters dahingehend festlegen möchten, ob er ausgewählt wurde oder nicht, können Sie Folgendes tun:
<TouchableOpacity style={this.props.venueFilters.includes('Bar')?styles.filterBtnActive:styles.filterBtn} onPress={()=>this.setFilter('Bar')}>
<Text numberOfLines={1}>
Bar
</Text>
</TouchableOpacity>
Auf welchem Set-Filter steht:
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: Die Funktion this.props.setVenueFilter(filters)
ist eine Redux-Aktion und this.props.venueFilters
ist ein Redux-Status.