ホームページ  >  記事  >  ウェブフロントエンド  >  Flexbox レイアウトを使用した React Native の概要

Flexbox レイアウトを使用した React Native の概要

不言
不言オリジナル
2018-07-03 17:58:161632ブラウズ

Flexbox の概念は React で導入されました。Flexbox は Web フロントエンド分野における CSS のレイアウト スキームであり、主に React Native の基本的な導入と Flexbox レイアウトの初期使用に関する関連情報を紹介します。サンプル コードを通じて非常に詳細に紹介されているので、必要な友人は参照してください

前書き

前回の記事で、著者は React Native アプリケーションのインストールとデバッグのプロセスでの経験の一部を共有しました。まだ読んでいない場合は、「React Native の基本と入門チュートリアル: React Native アプリケーションをデバッグするための小さなステップ」をクリックしてください。

この記事では、Flexbox レイアウトとは何か、その使用方法を一緒に学びましょう。

1. 長さの単位

レイアウトを開始する前に、React Native コンポーネント スタイルを記述するとき、長さには単位がないことを最初に知っておいてください。これは、「デバイスのピクセル密度に依存しない」ことを意味します。ピクセル」。

これをどう理解しますか?

画面上の最小の発光点がピクセルに対応することがわかっています。

次の 3 つの長方形が、画面サイズは同じで解像度が異なる 3 つのデバイスを表しているとします。

図 1. 同じサイズで解像度が異なるデバイス

画像上のそれぞれの小さなグリッドは実際にはピクセルを表します。物理サイズは同じですが解像度が異なるこれら 3 つのデバイスでは、ピクセルのサイズが異なることがわかります。

インターフェイス要素のサイズをピクセル単位で、たとえば高さ 2 ピクセルに設定すると、長さ 2 ピクセルのデバイスは次のようになります:

図 2. さまざまな解像度での実際の高さ2px

実際に表示される長さは異なります。

同じ物理サイズの画面では (物理サイズが同じであれば、解像度が高くても低くても)、長さの 1 単位で表される物理サイズは同じです。この種の単位には、解像度に依存しない名前を付け、密度に依存しないピクセル (略して dp) と呼びます。これは実際には Android システムで使用される長さの単位です。

たとえば、幅 2dp、高さ 2dp のコンテンツは、解像度は異なるが画面サイズが同じデバイス上でも同じ物理サイズで表示されます。 (余談: Android 開発者の中には、クリック可能なすべてのボタンの幅と高さを 48 dp 以上にすることを推奨している人もいます。)

図 3. 同じサイズの画面上の 2dp * 2dp サイズのコンテンツの物理的占有率は一貫しています

Android のフォント サイズは、スケール独立ピクセル (略して sp) と呼ばれる別の単位を使用します。この単位は dp に非常に似ていますが、通常はフォント サイズの設定に使用されます。それによって設定されるフォントは、システムのフォント サイズに応じて変更される可能性があります。

ピクセルとdpの間には、px = dp * (dpi/160)という公式があります。

dpi は dot per inch の略で、1 インチあたりのピクセル数を表します。これには独自の計算式もありますが、ここでは詳しく説明しません。デバイスの解像度に依存しないユニットを使用する理由は、主に、異​​なる解像度のデバイス上でアプリケーションの見た目に一貫性を持たせるためであることを知っておいてください。

RNにもdpに似た長さの単位があります。この長さで画面が何ユニットになるかを知りたい場合は、react-native パッケージに 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 = width *xelRadio、1920 = height *xelRatio

2. Flexbox レイアウト

Flexbox レイアウト、これはフレキシブル ボックス モデル レイアウトです。 Android 開発の経験がある友人は、LinearLayout、RelativeLayout、FrameLayout などのレイアウト方法をまだ覚えているかもしれませんが、CSS について詳しく知っている Web 開発者にとっては、フレックスボックス レイアウトを使用すると、間違いなく開発経験がより快適になるでしょう。

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,叫做侧轴,或者交叉轴。

在盒子中,排列项目又四个方向:水平的正反两个,垂直的正反两个。

结构代码:

<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: &#39;#ffe289&#39;,
flexDirection: &#39;row&#39;
},
rowReverse: {
flexDirection: &#39;row-reverse&#39;
},
column: {
backgroundColor: &#39;#ffe289&#39;,
flexDirection: &#39;column&#39;
},
columnReverse: {
flexDirection: &#39;column-reverse&#39;
},

图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在里面:

结构代码:

<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: &#39;#ffe289&#39;,
display: &#39;flex&#39;
}

图6. 默认的flex

justify-content设置items在主轴方向的如何分布,比如,如果我们加上justifyContent: 'space-between'

defaultFlex: {
height: 300,
backgroundColor: &#39;#ffe289&#39;,
display: &#39;flex&#39;,
justifyContent: &#39;space-between&#39;
}

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为固定大小时撑满剩余的盒子空间,就仿佛具有弹性一样。

结构代码:

<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: &#39;orange&#39;,
},
flex2: {
flexGrow: 2,
backgroundColor: &#39;lightblue&#39;,
},
flex3: {
flexGrow: 3,
backgroundColor: &#39;green&#39;,
},

图9. 按比例分布

需要注意的是,如果父容器的尺寸为零(即没有设置宽高,或者没有设定flex),即使子组件如果使用了flex,也是无法显示的。

所以这里最外层的使用了flex布局的,flex:1,表示让它占据了垂直的整个空间。

三、小小实战演练

让我们来简单使用flex布局,对之前的例子稍加调整,实现一个头部,底部固定高度,中间内容占满剩下的屏幕的布局:

第一步,调整结构:

<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: &#39;orange&#39;,
},
body: {
flexGrow: 1,
backgroundColor: &#39;lightblue&#39;,
},
footer: {
height: 60,
backgroundColor: &#39;green&#39;,
}

图10. 有头尾的布局

第二部,给header添加标题。

我们让头部的分成3部分,左边模拟一个返回按钮,中间显示标题文字,右边模拟一把小叉:

<View style={styles.header}>
 <Text style={styles.back}>返回</Text>
 <Text style={styles.title}>这是一个标题</Text>
 <Text style={styles.exit}>×</Text>
</View>

需要把header的flexDirection设置为水平方向:

header: {
height: 60,
backgroundColor: &#39;orange&#39;,
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;
},
back: {
color: &#39;white&#39;,
marginLeft: 15
},
title: {
flexGrow: 1,
fontSize: 20,
color: &#39;white&#39;,
textAlign: &#39;center&#39;
},
exit: {
marginRight: 20,
fontSize: 20,
color: &#39;white&#39;
}

图11. header有了标题

第三步,我们可以把footer三等分,模拟成菜单的样子:

<View style={styles.footer}>
 <Text style={styles.firstMenu}>添加</Text>
 <Text style={styles.menu}>删除</Text>
 <Text style={styles.menu}>修改</Text>
</View>

添加样式:

footer: {
height: 60,
backgroundColor: &#39;green&#39;,
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;
},
menu: {
flexGrow: 1,
textAlign: &#39;center&#39;,
borderColor: &#39;white&#39;,
borderLeftWidth: 1,
color: &#39;white&#39;
},
firstMenu: {
flexGrow: 1,
textAlign: &#39;center&#39;,
color: &#39;white&#39;
},

图12. footer三等分 模拟菜单

最后,让我们在body里也填入几个带按钮的输入框。

引入TextInput和Button组件,然后把它们分三组放入body中,

<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: &#39;lightblue&#39;,
},
inputRow: {
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;,
marginLeft: 10,
marginRight: 10
},
textInput: {
flex: 1
},
btn: {
minWidth: 60
}

flex布局的一个常用实践是,部分内容固定宽高,让剩下的内容自适应。

像上面这样,我们给Button有一个最小宽度,且TextInput的flexGrow为1,这样的做法可以实现,TextInput总是占满剩下的宽度,且可伸缩。

看了上面的例子,是否觉得在React Native中使用Flexbox布局也挺简单呢?

希望这是个不错的开始。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

基于React和Redux的SSR的实现方法

echarts同一页面中四个图表切换的js数据交互方法

以上がFlexbox レイアウトを使用した React Native の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。