搭建基礎環境
- jdk(必須,不解釋)
- sdk(建議使用android studio,集成sdk以及模擬器)
- genymotion(如果是使用真機或者android studio自帶的模擬器,可以選擇不裝)
- nvm(node版本控制器,需要node4.0以上版本)
以上配置不是必須,可自行選擇適合自己的環境,部分安裝過程可能會涉及到翻墻,需要配置代理
配置踩坑記錄
genymotion
這里選擇genymotion模擬器來講解,也會提一下android studio自帶的模擬器的一些注意點,使用真機的朋友可跳過這段。
genymotion的安裝有2種模式,一種是帶有oracle vm virtualbox虛擬機,另外一種是純凈版,genymotion的運行依賴virtualbox虛擬機。
選擇下載android6.0-api 23模擬器
(如果無法顯示api列表,請配置代理settings->network->use http proxy)
啟動模擬器,可能會有部分人卡在android啟動界面上面,無法進入
genymotion的運行基于x86的架構,比起arm,x86的性能更流暢。我們需要使用x86架構的話,還需要安裝haxm。
1、打開sdk manager->extras->intel x86 emulator accelerator,安裝即可,如果沒有任何東西顯示,還是代理問題,tools->options->proxy settings
2、進入c:\users\用戶\appdata\local\android\sdk\extras\intel\hardware_accelerated_execution_manager
安裝intelhaxm-android.exe,安裝出錯,請參考這里
至此我們就能進入模擬器界面
android studio
如果想使用android studio自帶模擬器,可以打開avd manager->create virtual device->選擇自己需要的android版本
值得注意的是,模擬器默認選擇x86架構,如果你不喜歡,你需要自己手動改成arm架構
nvm
這里選擇用nvm來控制node版本,如果你已經裝過node4.0以上的版本,就跳過這里。
安裝方式和使用文檔,github上面講的很清楚,這里說下代理的配置,其實也就是npm的代理,配置全局代理
1
2
|
npm config set proxy=you proxy npm config set https-proxy=you https proxy |
react-native初始化
心理默默祈禱以下命令千萬不要錯誤。。。
1
2
3
4
5
|
npm install -g react- native -cli react- native init awesomeproject cd awesomeproject react- native start react- native run-android |
果然。。。好吧,這里分享下自己遇到的一些問題
- npm install -g react-native-cli:出錯的最大可能就是node版本低于4.0或者代理沒配置成功
- react-native run-android:這個命令會下載gradle依賴,執行失敗的原因大部分也是因為代理的問題
進入c:\users\用戶\appdata\.gradle,打開gradle.properties(不存在就新建一個),修改
1
2
3
4
|
systemprop.https.proxyhost=you https proxy systemprop.https.proxyport=you https proxyport systemprop.http.proxyhost=you proxy systemprop.http.proxyport=you proxyport |
總算是把android應用程序跑起來了,真累人啊
布局
這里以三種經典布局來講解react-native布局概念,主要以flexbox為主,react native中有兩個基本元素< view >與< text >,分別類似于web端div和span,用于布局和修飾。需要注意的是,react native不是所有的css屬性都支持,這里有react native所支持的css屬性。
準備工作
在jsx中寫樣式還是有點不習慣,這里使用react-native-css模塊來編寫樣式,安裝、使用過程如下:
1
2
|
npm install react- native -css -g react- native -css -i style.css -o style.js --watch |
布局講解
左右布局
由于是橫向布局,我們需要flex-direction: row(默認縱向布局),左右以1:1方式排版,就都需要flex:1,布局容器也需要加上flex:1,表示為伸縮容器。由于react native沒有br標簽,需要換行只能將換行符插入。
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
wrap { flex: 1 ; flex-direction: row; background-color: yellow; } left{ flex: 1 ; background-color: #64ba9d; } right{ flex: 1 ; background-color: #008e59; } text{ padding: 10 ; font-size: 16 ; color:#eeeeee; line-height: 20 ; text-align: center; } |
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<view style={styles.wrap}> <view style={styles.left}> <text style={styles.text}> 這是左側欄{ '\n' } 這是左側欄{ '\n' } 這是左側欄{ '\n' } 這是左側欄{ '\n' } </text> </view> <view style={styles.right}> <text style={styles.text}> 這是右側欄{ '\n' } 這是右側欄{ '\n' } 這是右側欄{ '\n' } 這是右側欄{ '\n' } </text> </view> </view> |
左中右布局
左右定寬,中間占滿。
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
wrap { flex: 1 ; flex-direction: row; background-color: yellow; } left{ width: 80 ; background-color: #64ba9d; } centent{ flex: 1 ; background-color: #a9ea00; } right{ width: 80 ; background-color: #008e59; } text{ padding: 10 ; font-size: 16 ; color:#eeeeee; line-height: 20 ; text-align: center; } |
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<view style={styles.wrap}> <view style={styles.left}> <text style={styles.text}> 這是左側欄{ '\n' } 這是左側欄{ '\n' } 這是左側欄{ '\n' } 這是左側欄{ '\n' } </text> </view> <view style={styles.centent}> <text style={styles.text}> 這是內容區{ '\n' } 這是內容區{ '\n' } 這是內容區{ '\n' } 這是內容區{ '\n' } </text> </view> <view style={styles.right}> <text style={styles.text}> 這是右側欄{ '\n' } 這是右側欄{ '\n' } 這是右側欄{ '\n' } 這是右側欄{ '\n' } </text> </view> </view> |
上中下布局
類似新聞和門戶app的布局,上下貼邊,中間為內容區。
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
wrap { flex: 1 ; flex-direction:column; } top{ height: 40 ; background-color: #008e59; } centent{ flex: 1 ; background-color: #64ba9d; } bottom{ height: 40 ; background-color: #a9ea00; } text{ padding: 10 ; font-size: 16 ; color:#fff; line-height: 20 ; text-align: center; } |
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<view style={styles.wrap}> <view style={styles.top}> <text style={styles.text}> 頭部信息 </text> </view> <view style={styles.centent}> <text style={styles.text}> 這是內容區{ '\n' } </text> </view> <view style={styles.bottom}> <text style={styles.text}> 尾部信息 </text> </view> </view> |
綜合布局
簡單模擬網易新聞app布局:
我們可以簡單看看app布局方式,總體來說就是上中下的布局方式,我們可以初步先編寫外部結構
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<view style={styles.wrap}> <view style={styles.top}> <text>頭部</text> </view> <view style={styles.cententwrap}> <text>新聞主題</text> </view> <view style={styles.bottom}> <text> 尾部導航 </text> </view> </view> |
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
wrap { flex: 1 ; flex-direction:column; } top{ height: 40 ; background-color: #ec403c; } cententwrap{ flex: 1 ; flex-direction:column; } bottom{ height: 40 ; } |
大致結構算是搭建完畢,開始完善頭部展示(偷懶、不想切圖,就用個title代替就好啦~~~)
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<view style={styles.wrap}> <view style={styles.top}> <text style={styles.toptitle}>網易</text> </view> <view style={styles.cententwrap}> <text>新聞主題</text> </view> <view style={styles.bottom}> <text> 尾部導航 </text> </view> </view> |
樣式表:
1
2
3
4
5
6
7
|
toptitle{ margin-top: 15 ; margin-left: 20 ; text-align: left; font-size: 14 ; color:#fff; } |
頭部內容完成之后,就完善內容區域的導航條,但是react-native并沒有提供ul、li標簽(也許以后有),這個是要view來代替ul,text代替li,代碼和數據如下:
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
var cententnav = [ '頭條' , '熱點' , '娛樂' , '體育' , '財經' ]; return ( <view style={styles.wrap}> <view style={styles.top}> <text style={styles.toptitle}>網易</text> </view> <view style={styles.cententwrap}> <view style={styles.cententnav}> { cententnav.map(function(el, index){ return <text style={styles.cententnavtext}> <text style={index == 0 ? styles.textr : "" }>{cententnav[index]}</text> </text> }) } </view> </view> <view style={styles.bottom}> <text> 尾部導航 </text> </view> </view> ); |
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
cententwrap{ flex: 1 ; flex-direction:column; } cententnav{ flex-direction: row; height: 20 ; margin-left: 5 ; margin-top: 5 ; margin-right: 5 ; } cententnavtext{ width: 60 ; font-size: 14 ; color: #9c9c9c; margin-left: 10 ; } |
新聞主題方面可以劃分為左右兩欄,左欄固定寬,右欄占滿,由于react-native不支持overflow:scroll屬性,這里會用到一個scrollview的滾動條組件來展示新聞概述,篇幅可能較長,底部就不再編寫了(就是懶~~),大家各自完善吧,以下是全部的布局代碼和樣式。
頁面結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
render: function() { // var repeatarr = array(100).join("1").split("") var cententnav = [ '頭條' , '熱點' , '娛樂' , '體育' , '財經' ], new_data = [ { img: "http://7xl041.com1.z0.glb.clouddn.com/new1.png" , title: "李克強宴請上合各參會領導人" , content: "稱會議闡釋了上合組織\“大家庭\”的深厚友誼和良好氛圍" , typeimg: "http://7xl041.com1.z0.glb.clouddn.com/new-type1.png" }, //.....類似數據 ]; return ( <view style={styles.wrap}> <view style={styles.top}> <text style={styles.toptitle}>網易</text> </view> <view style={styles.cententwrap}> <view style={styles.cententnav}> { cententnav.map(function(el, index){ return <text style={styles.cententnavtext}> <text style={index == 0 ? styles.textr : "" }>{cententnav[index]}</text> </text> }) } </view> <scrollview style={styles.centent}> { new_data.map(function(el, index){ return ( <view> <view style={styles.cententli}> <image source={{uri: new_data[index].img}} style={styles.cententimg} /> <view style={styles.rightcentent}> <text style={styles.cententtitle}>{new_data[index].title}</text> <text style={styles.cententcentent}>{new_data[index].content}</text> </view> <image source={{uri: new_data[index].typeimg}} style={styles.cententtype} /> </view> <view style={styles.line}></view> </view> ) }) } </scrollview> </view> <view style={styles.bottom}> <text style={styles.text}> 尾部信息 </text> </view> </view> ); } |
樣式表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
wrap { flex: 1 ; flex-direction:column; } top{ height: 40 ; background-color: #ec403c; } toptitle{ margin-top: 15 ; margin-left: 20 ; text-align: left; font-size: 14 ; color:#fff; } cententwrap{ flex: 1 ; flex-direction:column; } cententnav{ flex-direction: row; height: 20 ; margin-left: 5 ; margin-top: 5 ; margin-right: 5 ; } cententnavtext{ width: 60 ; font-size: 14 ; color: #9c9c9c; margin-left: 10 ; } centent{ flex: 1 ; flex-direction:column; borderbottomwidth: 1 ; } cententli{ flex-direction: row; margin-left: 10 ; margin-right: 10 ; } cententimg{ width: 80 ; height: 80 ; } cententtitle{ font-size: 16 ; color: # 232323 ; margin-bottom: 3 ; } cententcentent{ font-size: 12 ; } rightcentent{ flex: 1 ; padding-left: 5 ; padding-top: 5 ; padding-right: 5 ; padding-bottom: 5 ; } cententtype{ width: 40 ; height: 22 ; position: absolute; bottom: 0 ; right: 0 ; } bottom{ height: 40 ; } text{ padding: 10 ; font-size: 16 ; color:# 000 ; line-height: 20 ; text-align: center; } textr{ font-weight: bold; color:#ec403c; } line{ height: 1 ; background-color: #e4e4e4; margin-left: 10 ; margin-right: 10 ; margin-top: 7 ; margin-bottom: 7 ; } |