Могу ли я сделать динамические стили в React Native?
скажем, у меня есть компонент с рендером, как это:
<View style={jewelStyle}></View>
где jewelStyle =
{
borderRadius: 10,
backgroundColor: '#FFEFCC',
width: 20,
height: 20,
},
как я могу сделать цвет фона динамически и случайным образом? Я пробовал
{
borderRadius: 10,
backgroundColor: getRandomColor(),
width: 20,
height: 20,
},
но это делает все экземпляры View имеют тот же цвет, я хочу, чтобы каждый из них был индивидуальным.
какие-либо советы?
10 ответов:
Я обычно делаю что-то вроде:
<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, } }
Да, вы можете и на самом деле, вы должны использовать
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'} } />
если вы все еще хотите воспользоваться
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свойстваViewустанавливается как массив, который объединяет вашу таблицу стилей с динамическими стилями.
были некоторые проблемы синтаксически. Это сработало для меня
<Text style={StyleSheet.flatten([styles.textStyle,{color: 'red'}])}> Hello </Text> const styles = StyleSheet.create({ textStyle :{ textAlign: 'center', fontFamily: 'Arial', fontSize: 16 } });
вы хотите, что-то вроде этого:
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> ); } });в этом примере я беру массив строк, содержащий данные для строк в компоненте, и сопоставляю его с массивом текстовых компонентов. Я использую встроенные стили для вызова
самый простой мой:
<TextInput style={styles.default, [ this.props.singleSourceOfTruth ? {backgroundColor: 'black'} : {backgroundColor: 'white'} ]}/>
Я знаю, что есть несколько ответов, но я думаю, что лучше и проще всего использовать состояние "изменить" - это цель состояния.
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> ); } }
если вы используете экран с фильтрами, например, и вы хотите установить фон фильтра относительно того, был ли он выбран или нет, вы можете сделать:
<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- это государственная тайна.
Да, вы можете сделать динамические стили. Вы можете передавать значения из компонентов.
сначала создайте 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> ); } }
Comments