react-native 结合ant-Design- mobil

作者: 有情怀的程序猿 | 来源:发表于2016-12-06 13:54 被阅读13596次

更新: 2017-06-19
新添加方法2 :
更新: 2017-06-23
简单封装 :
更新: 2017-07-03
发现需要使用的地方比较多, 最后封装成函数 :

-现-在的项目使用的是react-native 结合ant-Design- mobile,
但是发现有些组件样式不好调,尤其是嵌套很多层的子组件的字体,颜色,
官方使用style={} 作为props 的方式传递, 但是嵌套很多层的子组件的部分样式没起作用(不知道为什么), 而且react-native中样式基本不具备继承性,除了Text, (想了解的同学可以看大神陈学家的https://segmentfault.com/a/1190000002658374)

1: 先说下解决方法的弊端:
  • 类似web端更改class样式, 只能单个组件的更改, 不能解决更改全局的样式,
    (有想做一键切换主题更改全局样式的这个方法暂时不行, 如果大家发现好的方法,欢迎大家提出)
  • 方法1 只可以在原有的样式对象上更改,不能添加新的样式对象,
    更新的方法2 可以添加新的样式属性
2: 说下解决方法:

方法1:

举个例子: 比如我们现在需要ant-Design- mobile组件中的SegmentedControl

home.js中引入组件SegmentedControl

// home.js
import { SegmentedControl  } from 'antd-mobile';
....
....
....
  render() {
    return(
      <View style={Global.container}>
        <SegmentedControl
          selectedIndex={this.state.selectedIndex}
          values={this.segmentedLabel}
          onChange={this.onChange}
        />
        {this.renderList()}
      </View>
    );
  }

发现字体太小,想调整样式按照组件给的方法, 使用 style= {[fomtStyle: 100]}传入样式 , 没有反应,

解决办法思路如下:

  • 1: 去 node_modules\antd-mobile\lib\segmented-control\index.android.js中源码, 发现字体组件使用的样式是itemText对象
  return _react2["default"].createElement(_reactNative.TouchableWithoutFeedback, { key: idx, onPress: function onPress(e) {
                    return _this2.onPress(e, idx, value);
                } }, _react2["default"].createElement(_reactNative.View, { style: [_style2["default"].item, itemRadius, {
                    backgroundColor: idx === selectedIndex ? tintColor : '#fff',
                    borderColor: tintColor                                                   来看这里
                }] }, _react2["default"].createElement(_reactNative.Text, { style: [_style2["default"].itemText, {
                    color: idx === selectedIndex ? '#fff' : tintColor
                }] }, value)));

2: 然后去此组件的style/index.js 中可以看到这个对象名,

itemText: {
textAlign: 'center',
fontSize: _default2["default"].font_size_caption_sm
}

> 3: 在`home.js`中引用`style/index.js` , 然后更改对象`itemText `的`fontSize值`
- 但是只可以在原有的样式对象上更改,不能添加新的样式对象,不知道为什么,
 (谁如果知道为什么, 麻烦告诉下)

....

//引用style/index.js
let IndexStyle = require('../../node_modules/antd-mobile/lib/segmented-control/style/index.js');

class Home extends Component {
constructor(props){
super(props);
this.state = {
selectedIndex: 0,
textSize: 50,
};

// 看这里看这里 更改对象itemText的fontSize值

IndexStyle.itemText = {
  fontSize: 30,
}

/* 想添加一个自己写的信样式对象上去, 结果没有起效果,
IndexStyle.bgColor = {
backgroundColor: 'red',
}
*/
this.segmentedLabel = ['待办', '已办'];
this.renderList = this.renderList.bind(this);
this.onChange = this.onChange.bind(this);
}

####方法2: 

同上 ,需要先去看源码, 需要改的样式,在源码中定位到名称

比如这里要更改InputItem [ant-design-mobile中的InputItem](https://github.com/ant-design/ant-design-mobile/blob/master/components/input-item/index.tsx) 我们需要看下结构, 想更改的样式在组件哪一个cleassName下
比如我们更改marginLeft 左边的距离

![FCZY%X89BF9TY68HUR5RGZT.png](https://img.haomeiwen.com/i3512128/167e023c31d0f085.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我们需更改styles.container, 
styles 则是  `import InputItemStyle from './style/index';`
所以在 [上一级的style文件中找到文件index.tsx](https://github.com/ant-design/ant-design-mobile/blob/master/components/input-item/style/index.tsx)
在里面可以看到



![NO]B_@YDH$SD%%H2NC$@3IH.png](https://img.haomeiwen.com/i3512128/762e9138d3511e73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我们就可以使用下面的方法来修改, 
具体思路就是把所有的样式都拿回来, 扔进一个新的对象, 然后更改, 最后在塞回去

import variables from 'antd-mobile/lib/style/themes/default'; //可能你会用的到,可能不需要, 暂时贴在这, 如果需要就添加, 默认的样式主题
import InputItemStyle from 'antd-mobile/lib/input-item/style/index'; //引入要更改组件的样式,

// 定义一个新的样式对象
const newStyle = {};

// 把需要更改的组件的所有样式扔进新的样式对象, 然后更改对应的样式

function changeStyle () {
for (const key in InputItemStyle) {
if (Object.prototype.hasOwnProperty.call(InputItemStyle, key)) {
newStyle[key] = { ...StyleSheet.flatten(InputItemStyle[key]) };
if (key === 'container') {
newStyle[key].marginLeft = 15;
}
}
}
}

.................................
// 塞回去

<InputItem
key={index}
在这里:
styles={StyleSheet.create(newStyle)}

            style={{marginLeft: 16,}}
            disabled={true}
            placeholder={'请输入'}
            placeholderTextColor={'#999'}
            labelNumber={6}
            value={this.state.formData[item.code]}
            type={item.style === 'number'? 'number': ''}
            maxLength={10}
            onChange={this.setInputValue.bind(this,item)}
            editable={this.state.editable}
          />

>我们不仅可以修改原有的样式, 还可以添加新的样式, 
局限性就是只能在别人定义好的className 中做操作, 并且得去看源码
上面的方法可以自己做个封装, 方便多次使用

import variables from 'antd-mobile/lib/style/themes/default';
import InputItemStyle from 'antd-mobile/lib/input-item/style/index';
import TextareaItemStyle from 'antd-mobile/lib/textarea-item/style/index';

//简单封装
const newStyle = {}; //InputItem
const TextareaStyle = {}; // 大文本
function changeStyle (newObj,style, cssType, cssName,value) {
for (const key in style) {
if (Object.prototype.hasOwnProperty.call(style, key)) {
newObj[key] = { ...StyleSheet.flatten(style[key]) };
if (key === cssType) {
newObj[key][cssName] = value;
}
}
}
}
changeStyle(newStyle,InputItemStyle,'container','borderBottomColor','#fff') // 更改input的下边
changeStyle(newStyle,newStyle,'input','fontSize',16) // 再次更改input的字体, 所以把上次更改后的样式做为基本样式(style)扔进去
changeStyle(TextareaStyle,TextareaItemStyle,'input','fontSize',16)


##### 在封装一次, 2017-07-03

import ModalStyle from 'antd-mobile/lib/modal/style/index';
import { StyleSheet } from 'react-native';

function changeStyle (newObj,style, data) {
for (const key in style) {
if (Object.prototype.hasOwnProperty.call(style, key)) {
newObj[key] = { ...StyleSheet.flatten(style[key]) };
if (data.length > 0){
data.map((item,index) => {
if( key === item.cssType ) {
item.val.map((items,indexs) => {
newObj[key][items.key] = items.value;
})
}
})
}
}
}
}

const newStyle = {};

let myStyle = [
{
cssType: 'body', // 要改的样式的类名字
val: [{key: 'paddingHorizontal', value: 0}] // 要更改或添加的样式 key 为样式名称, value为值
},
{
cssType: 'header',
val: [
{key:'textAlign', value: 'left'},
{key:'color', value: '#fff'},
{key:'borderTopLeftRadius', value: 5},
{key:'borderTopRightRadius', value: 5},
{key:'backgroundColor', value: '#036b74'},
{key:'paddingTop', value: 10},
{key:'paddingBottom', value: 10}
]
},
{
cssType: 'innerContainer',
val: [{key: 'paddingTop', value: 0}]
}
]

changeStyle(newStyle,ModalStyle,myStyle)

>`changeStyle(newStyle,ModalStyle,data)`
`newStyle `新命名的空对象,
`ModalStyle` 从 `antd-mobile/xx/style` 中引入的原样式对象,
`cssType` 要改的样式的类名字` (cssType: 'innerContainer',)`, 和更改的css样式名称 `key` , 及值 `value` 
例: `(val: [{key: 'paddingTop', value: 0}])`


ok, 更改结束, 此方法基本就能满足平时样式更改,不仅可以更改原有样式, 还能添加样式.
希望阿杜的这个方法能帮到你, 如果大家有更好的方法欢迎您一定要提出,  谢谢

相关文章

网友评论

    本文标题:react-native 结合ant-Design- mobil

    本文链接:https://www.haomeiwen.com/subject/gffrmttx.html