游戲的界面如下

CrosswordPuzzle
從設(shè)計(jì)圖可以看出頁面主要分為3部分,頂部提示Note、棋盤和底部欄,React Native是使用Flex語法做布局的,這種格局咋一看就覺得應(yīng)該使用justifyContent: 'space-around'來實(shí)現(xiàn)兩端對(duì)齊。
但使用space-around會(huì)有一個(gè)問題,就是用戶在底部欄輸入時(shí),上面的Note就看不到了,這樣感覺并不好。
為了讓Note一直放在屏幕上,將Note改為使用絕對(duì)定位position: 'absolute', top: 20,頁面使用justifyContent: 'flex-end'讓其它View排列在頁面底部。
為了讓Note一直放在其它View的上面以保證不被覆蓋,在寫代碼時(shí)要將它放到其它View的后面,這樣后渲染的View就會(huì)保持在其它View的前面。
所以經(jīng)過上面的思考,布局的基本代碼如下,全部源碼可以到Github上查看
<View>
<View style={styles.board}>
{ grids }
</View>
<View style={styles.note}>
{
selectedGrid && <Note
horizontalNote={selectedGrid.horizontalNote}
verticalNote={selectedGrid.verticalNote}
horizonActive={selectState.horizontal}
/>
}
</View>
<BottomLayout
style={styles.bottomLayout}
handleInput={this._handleInput}
onHintClick={this._onHintClick}
/>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
width: width,
position: 'relative',
justifyContent: 'flex-end',
alignItems: 'center',
},
board: {
width: config.gridWidth * 10,
height: config.gridWidth * 10,
marginBottom: 40,
},
note: {
position: 'absolute',
top: 20,
},
bottomLayout: {
flex: 1,
flexDirection: 'row'
}
});
填坑記
-
如果是引入的其它組件,在部件上使用的style并不會(huì)傳入組件內(nèi)部,如上面代碼中的BottomLayout的style并不會(huì)覆蓋組件內(nèi)部的style,通過react-devtools查看DOM結(jié)構(gòu)就能看出來,引用時(shí)定義的style是放在額外的一層wrapper里,組件內(nèi)的View是被嵌套著的,兩者不在同一層,所以style并不會(huì)被覆蓋
BottomLayout DOM - 絕對(duì)定位的組件不能進(jìn)行動(dòng)態(tài)插入,如上面代碼的Note部分,外層有一層View做為占位,即使Note不需要顯示,這個(gè)View也是占據(jù)在那里,只是內(nèi)部沒有任何元素,在界面上完全看不到。
這個(gè)可以實(shí)驗(yàn)一下,去掉外層的View,將Note部分代碼做如下修改,再刷新下界面。刷新后的界面如下圖。
可以看到Note還是作為文檔流的一部分按照flex-end排列,并沒有按照預(yù)想的那樣固定在頂部。不知道這是否是Bug,或者是我使用方法有誤
{
selectedGrid && <Note style={[styles.note]}
horizontalNote={selectedGrid.horizontalNote}
verticalNote={selectedGrid.verticalNote}
horizonActive={selectState.horizontal}
/>
}

絕對(duì)定位失效
