做前端开发,熟悉了HTML+CSS+JS的开发模式,如果不看RN原理,直接用老一套的逻辑思维上手RN,可能会大跌眼镜。高效开发的前提,需要学习并理解RN的原理。本文主要记录内容是,关于RN开发的HTML层面上的问题。

一、RN的HTML

RN提供的组件(在HTML中叫标签)中常用的有:

1.View-视图容器

可用属性

  • style={[Styles.nav, { borderColor: '#0ff' }]}
  • onLayout={(event) => { this.getViewInfo; }}
  • getViewInfo(event){

    console.log(event.nativeEvent.layout.height)

    }//获取视图容器的宽高属性

2.Text-文本容器

可用属性:

  • style={{textAlign:'center'}]}
  • numberOfLines={2}

    该组件设置固定宽度后超出的文字会在第二行的末尾以省略号的形式显示

3.TouchableOpacity-按钮/可触发点击事件的区域

可用属性:

  • onPress={()=>{this.todo()}}
  • activeOpacity={1}

    点击触发后内容没有消隐效果

4.ScrollView和FlatList-滚动列表,属性较多,不罗列;

5.Image-图片容器

可用属性:

  • source={require('.../.../img/top.png')}

6.Modal-模态框

  • 可作为toast的无需操作2秒消失的警告或提示信息
  • 也可作为有交互按钮的操作提示对话框;

二、RN的CSS

1.样式声明:

const StylesComponent = StyleSheet.create({

text:{fontSize: 14},

textColor:{color:'#fff'}

});

2.样式使用的四种形式:

<Text style={StylesComponent.text}></Text>

<Text style={{color:'#fff'}}></Text>

<Text style={[StylesComponent.text,{color:'#fff'}]}></Text>

<Text style={[StylesComponent.text,StylesComponent.textColor]}></Text>

3.RN的盒子模型:box-sizing: border-box;

width包括border和padding

4.CSS属性的书写方式为驼峰式,如fontSize;

5.布局方式为flexbox,弹性盒子模型

在 React-Native 中的flexbox 是css3中flexbox的一个子集,并不支持所有的flexbox属性

6.常用的CSS属性:官方给出的全部属性如下,

React-native Valid style props: [
"alignContent",
"alignItems",//父元素的样式,子元素在当前侧轴方向上的对齐方式;如flexDirection为row时,center表示子元素垂直居中;子元素如果设置了alignSelf属性,则会重写该属性
"alignSelf",//子元素的样式,设置该元素单独在侧轴方向上的对齐方式
"aspectRatio",//元素宽高比,RN独有,设置了图片的宽度后,只需设置好这个属性,就不需要设置图片的高度
"backfaceVisibility",
"backgroundColor",
"borderBottomColor",
"borderBottomLeftRadius",
"borderBottomRightRadius",
"borderBottomWidth",
"borderColor",
"borderLeftColor",
"borderLeftWidth",
"borderRadius",
"borderRightColor",
"borderRightWidth",
"borderStyle",
"borderTopColor",
"borderTopLeftRadius",
"borderTopRightRadius",
"borderTopWidth",
"borderWidth",
"bottom",
"color",
"decomposedMatrix",
"direction",
"display",//控制组件显示与隐藏,隐藏后不占位
"elevation",
"flex",
"flexBasis",
"flexDirection",//默认为column,子元素垂直排列,可设置为row,子元素水平排列
"flexGrow",
"flexShrink",
"flexWrap",
"fontFamily",
"fontSize",
"fontStyle",
"fontVariant",
"fontWeight",
"height",
"includeFontPadding",
"justifyContent",
"left",
"letterSpacing",
"lineHeight",
"margin",
"marginBottom",
"marginHorizontal",
"marginLeft",
"marginRight",
"marginTop",
"marginVertical",
"maxHeight",
"maxWidth",
"minHeight",
"minWidth",
"opacity",
"overflow",
"overlayColor",
"padding",
"paddingBottom",
"paddingHorizontal",
"paddingLeft",
"paddingRight",
"paddingTop",
"paddingVertical",
"position",//RN元素定位类型只有两种:relative相对于正常文档流进行偏移;absolute相对于父元素进行绝对定位,不管父元素设置position属性与否;
"resizeMode”,(cover图片铺满)
"right",
"rotation",
"scaleX",
"scaleY",
"shadowColor",
"shadowOffset",
"shadowOpacity",
"shadowRadius",
"textAlign",
"textAlignVertical",
"textDecorationColor",
"textDecorationLine",
"textDecorationStyle",
"textShadowColor",
"textShadowOffset",
"textShadowRadius",
"tintColor",
"top",
"transform",transform:[{rotate:'30deg'},{translate:[-waterMarkW,0]}]
"transformMatrix",
"translateX",
"translateY",
"width",
"writingDirection",
"zIndex"
]

三、常规布局方案

1.需求一:

  • 布局为flex布局
  • 子元素水平布局
  • 并且会每三个元素自动换行
  • 两边间距10px
  • 中间间距16px;

Label组件实现代码如下:

class Label extends Component {
constructor(props) {
super(props);
this.state = {
selected: false,
};
} clicked() {
if (this.state.selected) {
this.setState({
selected: false,
});
} else {
this.setState({
selected: true,
});
}
} render() {
return (
<TouchableOpacity onPress={() => { this.clicked(); }} activeOpacity={1}>
<View
style={{
borderWidth: D(1),
width: D(64),
height: D(24),
borderRadius: D(2),
alignItems: 'center',
justifyContent: 'center',
marginTop: D(16),
backgroundColor: this.state.selected ? '#fff' : '#f5f5f5',
borderColor: this.state.selected ? '#ff6700' : '#f5f5f5',
marginRight: (this.props.index + 1) % 3 == 0 ? D(10) : D(16),
}}
>
<Text
style={{
color: this.state.selected ? '#ff6700' : '#757575',
}}
>{this.props.item}
</Text>
</View>
</TouchableOpacity>
);
}
}

2、maxWidth失效

布局如下,maxWidth失效:

<View style={{ maxWidth: 100 }}>
<Text>123</Text>
</View>

改变方案如下,maxWidth生效:

<View style={{ flexDirection: 'row', justifyContent: 'flex-start' }}>
<View style={{ maxWidth: 100 }}>
<Text>123</Text>
</View>
</View>

生效原因,改变了主轴的方向,flex水平布局时maxWidth才会生效,但flex默认为垂直布局;

3.、获取TextInput对象

<TextInput
onChange={(e) => { this.onChange(e); }}
ref="textInput"
/>
onChange(e) {
console.log(e);// {eventCount:'',target:'',text:''}
}

四、获取组件的宽高和位置信息

react-native 获取组件的尺寸有两种方式:

第一种方式使用元素自身的onLayout属性去获取

但是这种方式有一个局限性:

  • 只有在初次渲染的时候才会触发这个函数,
  • 此种方法获取的是组件相对于父组件的位置坐标

第二种方式,使用react-native中的findNodeHandle和UIManager来获取组件的尺寸

这里封装一个layout的函数,当我们需要获取组件的宽度和高度或者位置信息时,就可以通过调用这个函数去获取。

  • layout函数接受一个ref参数,这个参数表示组件的实例,传入组件的实例后,然后通过findNodeHandle方法获取组件节点。
  • UIManager.measure接受两个参数,
    • 第一个参数是通过findNodeHandle获取的组件节点

    • 第二个参数是获取成功的回调

      • 回调有6个参数:

        x,y表示组件的相对位置

        width,height表示组件的宽度和高度

        pageX,pageY表示组件相对于屏幕的绝对位置。
import { findNodeHandle, UIManager } from 'react-native';
<TextInput
onChange={(e) => { this.onChange(e); }}
ref="textInput"
/>
onChange(e) {
this.layout(this.refs.textInput)
.then((item) => {
console.log(item);// 可以在then回调中同步获取数据{x,y,width,height,pageX,pageY}
});
} layout(ref) {
const handle = findNodeHandle(ref); return new Promise((resolve) => {
UIManager.measure(handle,
(x, y, width, height, pageX, pageY) => {
resolve({
x, y, width, height, pageX, pageY,
});
});
});
}

最新文章

  1. 看的oracle数据库视频 记的一点笔记
  2. 跟我一起学WCF(3)——利用Web Services开发分布式应用
  3. Bonobo Git Server (Simple git server for Windows.) 测试备忘
  4. linux之i2c子系统架构---总线驱动
  5. linux下从源代码安装git
  6. 21个很棒的jQuery分页插件下载
  7. CSS远程加载字体
  8. JS日期显示格式 yyyy-MM-dd hh:mm:ss
  9. PHP关于表单提交 后 post get分页
  10. 浅谈js中的正则表达式
  11. java web开发中遇到的问题及解决方案(个人学习日志,持续更新)
  12. pat 1001 A+B Format
  13. BZOJ_2962_序列操作_线段树
  14. 16. Antimalware (反病毒 3个)
  15. poj 2074
  16. 递推2--过河卒(Noip2002)
  17. NSString 与C++ string字符串的互转(转)
  18. 【linux使用】bash shell命令行常用快捷键
  19. linux 编译win32程序
  20. NET Framework安装失败的麻烦

热门文章

  1. 7月22 Linux作业-文件管理
  2. [LC]219题 Contains Duplicate II (存在重复元素 II )
  3. CentOS7安装PPTP
  4. SecureCRT 多个会话显示在同一窗口
  5. 精通awk系列(8):awk划分字段的3种方式
  6. 【阿里巴巴-高德-汽车事业部】【内推】Java技术专家、前端技术专家、C++技术专家(长期招聘)
  7. 微信小程序 子组件给父组件传参
  8. [ubuntu篇] 使用Hexo建立个人博客,自定义域名https加密,搜索引擎google,baidu,360收录
  9. tensorflow的函数
  10. python网络爬虫之入门[一]