在 react-native 中,StyleSheet 是一个比较好的样式和代码分离的方式,但是默认提供的 StyleSheet 不是很充足。一个很常见的点击之后发生颜色变化的文本控件都没有默认提供,如果说我们自定义一个 TextHighlightable 控件,同时又希望能在 StyleSheet 中来指定字体点击之后的颜色的话,那就需要对默认提供的 StyleSheet 系统进行扩充了。
在目前的版本 0.14.2 中,react-native 没有提供官方的扩充 StyleSheet 的方式,我们这里需要使用比较hack的方法来进行,不保证兼容未来的版本。
StyleSheet 相关的代码是放置在目录 react-native/Libraries/StyleSheet 下面的,当我们使用下面这样的代码来创建一个样式时
var styles = StyleSheet.create({ container: { borderRadius: 4, borderWidth: 0.5, borderColor: '#d6d7da', }, title: { fontSize: 19, fontWeight: 'bold', }, activeTitle: { color: 'red', }, });
会先进入到 StyleSheetValidation.js 中进行样式的格式验证,扩充 StyleSheet,主要需要做的事情就是通过 addValidStylePropTypes 来扩充 StyleSheetValidation。
例如,在 TextHighlightable 控件中增加 colorHighlight 样式,就像下面这样:
var styles = StyleSheet.create({ textButton: { color: '#d6d7da', colorHighlight: 'red', }, });
如果不扩充 StyleSheetValidation 的话,程序就会出现错误,“Error: Invariant Violation: “colorHighlight” is not a valid style property.”。扩充也很简单,在创建样式之前,增加下面一些代码就可以了。
var StyleSheetValidation = require('StyleSheetValidation'); var ReactPropTypes = require('ReactPropTypes'); var ViewStylePropTypes = require('ViewStylePropTypes'); var TextHighlightableStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), { colorHighlight: ReactPropTypes.string, }); StyleSheetValidation.addValidStylePropTypes(TextHighlightableStylePropTypes);
然后,我们就可以在 stylesheet 中使用 colorHighlight 了。在 TextHighlightable 组件中,我们可以使用 flattenStyle 来获取到所配置的 style 信息,如:
render() { var style = _.extend({}, flattenStyle(this.props.style)); if(this.state.isPressing && style.colorHighlight) { style.color = style.colorHighlight; } delete style['colorHighlight']; return ( <TouchableWithoutFeedback {...touchableProps}> <Text style={style}>{this.props.children}</Text> </TouchableWithoutFeedback> ); },