React에 Flexbox 개념이 도입되었습니다. Flexbox는 웹 프론트엔드 분야의 CSS 레이아웃 체계입니다. 다음 글에서는 React Native의 기본 소개와 초기 사용에 대한 관련 정보를 주로 소개합니다. 코드 소개는 매우 상세합니다. 필요한 친구는
Foreword#🎜🎜을 참조하세요. #
이전 기사에서 저자는 React Native 애플리케이션을 설치하고 디버깅하는 과정에서 자신의 경험을 공유했습니다. 아직 보지 못했다면 "React Native Basics & Introductory Tutorial: A Small"을 클릭하세요. React Native 애플리케이션 디버깅 단계'를 참조하세요. 이 글에서는 Flexbox 레이아웃이 무엇인지, 어떻게 사용하는지 알아보겠습니다.1. 길이 단위
레이아웃을 시작하기 전에 먼저 알아야 할 사항은 다음과 같습니다. React Native 구성 요소 스타일을 작성하면 길이에 단위가 없습니다. "장치 픽셀 밀도와 무관한 논리적 픽셀"을 나타냅니다. 이걸 어떻게 이해하시나요? 우리는 화면에서 가장 작은 발광점이 픽셀에 해당한다는 것을 알고 있습니다. 다음 세 개의 직사각형은 화면 크기는 동일하지만 해상도가 다른 세 개의 장치를 나타낸다고 가정합니다.#🎜🎜 #Figure 1. 해상도가 다른 동일한 크기의 장치
사진의 각 작은 격자는 실제로 픽셀을 나타냅니다. 물리적 크기는 동일하지만 해상도가 다른 세 장치에서 픽셀 크기가 다르다는 것을 알 수 있습니다.
인터페이스 요소의 크기를 픽셀 단위로 설정하면(예: 높이 2px) 길이가 2px인 장치는 다음과 같습니다.
#🎜 🎜## 🎜🎜#그림 2. 다양한 해상도에서 2px의 실제 높이실제 표시 길이는 다릅니다.
우리는 동일한 물리적 크기의 화면에서(누가 더 높은 해상도를 가지고 있든 더 낮은 해상도를 가지고 있든, 물리적 크기가 동일하다면) 길이 단위를 원합니다. 단위는 물리적 차원이 동일함을 나타냅니다. 이러한 종류의 단위는 해상도와 무관해야 합니다. 밀도 독립형 픽셀, 줄여서 dp라는 이름을 지정해야 합니다. 이는 실제로 안드로이드 시스템에서 사용되는 길이 단위입니다.
예를 들어, 너비가 2dp이고 높이가 2dp인 콘텐츠는 해상도는 다르지만 화면 크기는 동일한 기기에서 동일한 물리적 크기를 표시합니다. (여담: 일부 Android 개발자는 클릭 가능한 모든 버튼의 너비와 높이가 48dp 이상이어야 한다고 권장합니다.)
그림 3. 2dp * 2dp 크기의 콘텐츠는 동일한 크기의 화면에서 동일한 물리적 크기를 차지합니다.Android는 글꼴 크기에 대해 크기 독립적 픽셀 또는 줄여서 sp라고 하는 다른 단위를 사용합니다. 이 단위는 dp와 매우 유사하지만 일반적으로 글꼴 크기를 설정하는 데 사용됩니다. 이를 통해 설정된 글꼴은 시스템 글꼴 크기에 따라 변경될 수 있습니다.
픽셀과 dp 사이에는 px = dp * (dpi/160)라는 공식이 있습니다.
dpi는 인치당 도트 수, 즉 인치당 픽셀 수를 의미하며, 여기서는 확장하지 않겠습니다. 장치 해상도와 독립적인 장치를 사용하려는 이유는 주로 다른 해상도를 가진 장치에서 응용 프로그램이 일관되게 보이도록 하기 위한 것입니다.
RN에도 dp와 비슷한 길이 단위가 있습니다. 이 길이를 기준으로 화면이 몇 단위로 측정되는지 알고 싶다면 반응 네이티브 패키지에 Dimensions를 도입하여 얻을 수 있으며 네이티브 시스템의 픽셀 비율도 확인할 수 있습니다.
import { Text, View, Dimensions, PixelRatio } from 'react-native'; const { height, width } = Dimensions.get('window'); const pxRatio = PixelRatio.get(); <View style={styles.container}> <Text style={styles.welcome}> {`width: ${width}, height: ${height}`} </Text> <Text style={styles.welcome}> {`pixel radio: ${pxRatio}`} </Text> </View>
은 다음과 같이 표시됩니다.
사진 4 . 현재 휴대폰 화면 정보현재 휴대폰 화면 너비는 360 유닛, 높이는 640 유닛을 차지하고 있음을 반영합니다. 픽셀 비율은 3이며 실제로는 1080*1920 픽셀의 휴대폰입니다. 그 중 1080 = 너비 * pixelRadio, 1920 = 높이 * pixelRatio
2 Flexbox 레이아웃
Flexbox 레이아웃은 유연한 상자 모델 레이아웃입니다. Android 개발 경험이 있는 친구들은 여전히 LinearLayout, RelativeLayout, FrameLayout 등과 같은 레이아웃 방법을 기억할 수 있지만, CSS에 대해 더 잘 아는 웹 개발자에게는 Flexbox 레이아웃을 사용하는 것이 확실히 더 편안한 개발 경험을 느낄 수 있을 것입니다. RN中的flexbox布局,其实源于CSS中的flexbox(弹性盒子)布局规范。其实它在CSS中还处于Last Call Working Draft(最终征求意见稿)阶段,但是主流浏览器对它都有了良好的支持。在RN中,几乎完全借鉴了其中的布局语义,同时更没有浏览器兼容的烦恼,用起来是很方便的。RN中只是把CSS的属性用camelCase写法代替连字符写法。后面还还会看到,默认的flex方向也不同。 理解弹性盒模型布局,首先要知道四个最基本的概念:Flex Container(容器),Flex Item(项),Flex Direction(方向)和Axis(轴)。 1.Flex Container 就是包裹内容的容器,需要把它的display设置为‘flex'(或者'inline-flex')。 以下6个属性设置在容器上。 alignItems 指定item在侧轴上的对齐方式 alignContent 指定item在多条轴上的对齐方式 flexDirection 指定主轴方向 flexWrap 指定item在主轴方向如何换行 flexFlow flexDirection属性和flexWrap属性的简写形式 justifyContent 指定item在主轴上的分布方式 2.Flex Item 容器做直接包裹的元素。所谓弹性盒布局,通常想要布局的东西就是它们。 以下6个属性设置在项目上。 alignSelf 每个item可以单独设置对齐方式 覆盖Flex Container给设置的alignItems order 指定item排列顺序 数字越小越靠前 flexGrow 指定item的拉伸比例 flexShrink 指定item的压缩比例 flexBasis 指定item在分配多余空间之前,占主轴的大小 flex 其实是 flexGrow flexShrink flexBasis的简写 3.Flex Direction and Axis 在弹性盒子中,项目默认沿着main axis(主轴)排列,和主轴垂直的轴叫做cross axis,叫做侧轴,或者交叉轴。 在盒子中,排列项目又四个方向:水平的正反两个,垂直的正反两个。 结构代码: 样式代码: 图5. flexDirection 由于网上关于flex布局讲解的资源挺丰富的,读者可以参考最后给出的连接,或者自行上网搜索,CSS中的和RN是相通的。 这里主要分享个人在学习过程中,觉得容易引起混淆的两个小点。 首先,justify-content和align-content这两个属性,可能比较容易搞错它们作用的方向。 其中,justify-content是设置items沿着主轴上是如何分布的。align-content是设置items沿着侧轴如何对齐的。 还是拿之前的例子,默认情况下,flex的方向是column(这个与移动端与web页面不同,在web页面用CSS设置flex布局,默认的fiex-direction是row,即水平从左往右)。 在移动端,主轴默认是垂直方向,从上往下。让我们把它的高度设置高一点,放3个item在里面: 结构代码: 样式代码: 图6. 默认的flex justify-content设置items在主轴方向的如何分布,比如,如果我们加上justifyContent: 'space-between' items就沿主轴分开了。 图7. justifyContent: 'space-between' 如果我们设置alignItems: 'center',项目就沿侧轴(这里就是水平轴)居中了。注意这两个属性是可以同时起作用的。 图8. justifyContent: 'space-between' 以及 alignItems: 'center' 然后,值得指出的是,flex这个属性,其实是flexGrow, flexShrink, flexBasis(对应的CSS属性flex-grow, flex-shrink和flex-basis)三个属性的结合。 我们通常在移动端看到的flex:1这个设置,其实是对flex-grow的设置。后者的默认值为0。使用把flex-grow设置为正整数的方法,可以让item按比例分布,或者在其他item为固定大小时撑满剩余的盒子空间,就仿佛具有弹性一样。 结构代码: 样式代码: 图9. 按比例分布 需要注意的是,如果父容器的尺寸为零(即没有设置宽高,或者没有设定flex),即使子组件如果使用了flex,也是无法显示的。 所以这里最外层的使用了flex布局的,flex:1,表示让它占据了垂直的整个空间。 三、小小实战演练 让我们来简单使用flex布局,对之前的例子稍加调整,实现一个头部,底部固定高度,中间内容占满剩下的屏幕的布局: 第一步,调整结构: 调整样式: 图10. 有头尾的布局 第二部,给header添加标题。 我们让头部的分成3部分,左边模拟一个返回按钮,中间显示标题文字,右边模拟一把小叉: 需要把header的flexDirection设置为水平方向: 图11. header有了标题 第三步,我们可以把footer三等分,模拟成菜单的样子: 添加样式: 图12. footer三等分 模拟菜单 最后,让我们在body里也填入几个带按钮的输入框。 引入TextInput和Button组件,然后把它们分三组放入body中, 添加样式: flex布局的一个常用实践是,部分内容固定宽高,让剩下的内容自适应。 像上面这样,我们给Button有一个最小宽度,且TextInput的flexGrow为1,这样的做法可以实现,TextInput总是占满剩下的宽度,且可伸缩。 看了上面的例子,是否觉得在React Native中使用Flexbox布局也挺简单呢? 希望这是个不错的开始。 以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网! 相关推荐: 위 내용은 Flexbox 레이아웃을 사용한 React Native 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!<View>
<View style={styles.row}>
<Text style={styles.item}>1</Text>
<Text style={styles.item}>2</Text>
<Text style={styles.item}>3</Text>
</View>
<View style={styles.rowReverse}>
<Text style={styles.item}>1</Text>
<Text style={styles.item}>2</Text>
<Text style={styles.item}>3</Text>
</View>
<View style={styles.column}>
<Text style={styles.item}>1</Text>
<Text style={styles.item}>2</Text>
<Text style={styles.item}>3</Text>
</View>
<View style={styles.columnReverse}>
<Text style={styles.item}>1</Text>
<Text style={styles.item}>2</Text>
<Text style={styles.item}>3</Text>
</View>
</View>
row: {
backgroundColor: '#ffe289',
flexDirection: 'row'
},
rowReverse: {
flexDirection: 'row-reverse'
},
column: {
backgroundColor: '#ffe289',
flexDirection: 'column'
},
columnReverse: {
flexDirection: 'column-reverse'
},
<View>
<View style={styles.defaultFlex}>
<Text style={styles.item}>1</Text>
<Text style={styles.item}>2</Text>
<Text style={styles.item}>3</Text>
</View>
</View>
defaultFlex: {
height: 300,
backgroundColor: '#ffe289',
display: 'flex'
}
defaultFlex: {
height: 300,
backgroundColor: '#ffe289',
display: 'flex',
justifyContent: 'space-between'
}
<View style={styles.container}>
<View style={styles.flex1}></View>
<View style={styles.flex2}></View>
<View style={styles.flex3}></View>
</View>
container: {
flex: 1
},
flex1: {
// height: 99,
flexGrow: 1,
backgroundColor: 'orange',
},
flex2: {
flexGrow: 2,
backgroundColor: 'lightblue',
},
flex3: {
flexGrow: 3,
backgroundColor: 'green',
},
<View style={styles.container}>
<View style={styles.header}></View>
<View style={styles.body}></View>
<View style={styles.footer}></View>
</View>
container: {
flex: 1
},
header: {
height: 60,
backgroundColor: 'orange',
},
body: {
flexGrow: 1,
backgroundColor: 'lightblue',
},
footer: {
height: 60,
backgroundColor: 'green',
}
<View style={styles.header}>
<Text style={styles.back}>返回</Text>
<Text style={styles.title}>这是一个标题</Text>
<Text style={styles.exit}>×</Text>
</View>
header: {
height: 60,
backgroundColor: 'orange',
flexDirection: 'row',
alignItems: 'center'
},
back: {
color: 'white',
marginLeft: 15
},
title: {
flexGrow: 1,
fontSize: 20,
color: 'white',
textAlign: 'center'
},
exit: {
marginRight: 20,
fontSize: 20,
color: 'white'
}
<View style={styles.footer}>
<Text style={styles.firstMenu}>添加</Text>
<Text style={styles.menu}>删除</Text>
<Text style={styles.menu}>修改</Text>
</View>
footer: {
height: 60,
backgroundColor: 'green',
flexDirection: 'row',
alignItems: 'center'
},
menu: {
flexGrow: 1,
textAlign: 'center',
borderColor: 'white',
borderLeftWidth: 1,
color: 'white'
},
firstMenu: {
flexGrow: 1,
textAlign: 'center',
color: 'white'
},
<View style={styles.body}>
<View style={styles.inputRow}>
<TextInput style={styles.textInput}></TextInput>
<Button style={styles.btn} onPress={() => {}} title="确定"></Button>
</View>
<View style={styles.inputRow}>
<TextInput style={styles.textInput}></TextInput>
<Button style={styles.btn} onPress={() => {}} title="非常确定"></Button>
</View>
<View style={styles.inputRow}>
<TextInput style={styles.textInput}></TextInput>
<Button style={styles.btn} onPress={() => {}} title="确定一定以及肯定"></Button>
</View>
</View>
body: {
flexGrow: 1,
backgroundColor: 'lightblue',
},
inputRow: {
flexDirection: 'row',
alignItems: 'center',
marginLeft: 10,
marginRight: 10
},
textInput: {
flex: 1
},
btn: {
minWidth: 60
}