如何用 React Native 創建一個iOS APP?(二)

我們書接上文《如何用 React Native 創建一個iOS APP?》,繼續來講如何用 React Native 創建一個iOS APP。接下來,我們會涉及到很多控件。

1 AppRegistry.registerComponent(

上述是定義應用程序的入口點。這也是 JavaScript 代碼開始執行的地方。
這是一個本地用戶界面反應的基本結構。我們定義的每個視圖將遵循相同的基本結構。
在本教程中,我們將創建一個既可以瀏覽書籍又能知道書籍介紹比如作者、標題或關于書籍的簡介。你還可以通過檢索書名或作者來查找你想要的書籍。下面我要介紹這個應用程序。我們將會使用谷歌圖書 API的數據。


如何用 React Native 創建一個iOS APP?(二)
添加一個標簽欄

該應用程序會有一個有兩項的標簽欄--- Featured 和 Search。我們將首先添加它。
雖然你擁有 index.ios.js 文件中所有的代碼,這是不推薦的,因為它會隨著應用程序的代碼的增加而混亂。為了更好的管理,我們要在不同的文件中創建類別。
創建兩個 JavaScript 文件在你項目的根目錄(和 index.ios.js 文件在相同的位置)。為 Search.js 文件和 Featured.js 命名。打開 Featured.js 并添加以下代碼。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Text,
    Component
   } = React;
 
var styles = StyleSheet.create({
    description: {
        fontSize: 20,
        backgroundColor: 'white'
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
});
 
class Featured extends Component {
    render() {
        return (
        <View style={styles.container}>
            <Text style={styles.description}>
              Featured Tab
            </Text>
        </View>
        );
    }
}
 
module.exports = Featured;

你應該熟悉以上那個代碼;它非常類似于我們之前看到的代碼。我們設置 Strict Mode,加載 react-native 模塊,創建視圖樣式,渲染UI 和渲染輸出()函數功能。最后一行代碼輸出 Featured 類從而使他更方便地被其他文件所用。請注意我們所說的 class 和 function有點不同于 index.ios.js。JavaScript 有不同的方式表示 class和 function。可以隨意選擇你喜歡的你風格。接下來的教材中,我們將使用上邊所使用的風格。
通過樣式表中的定義,我們可以看出基本的 CSS 屬性。我們為視圖中的文本和中心內容設置字體大小和背景顏色。但你可能不熟悉 flex:1樣式。這是 flexbox,CSS 規范的最新附加功能。flex:1 使元素標記容器占用的空間在屏幕上不被兄弟元素占用,否則它只能通過占用足夠的空間來適應它的內容。以后我們將更加重視 flex。了解更多的Flexbox 樣式,你可以閱讀本指南。
在 Search.js 添加以下程序。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Text,
    Component
   } = React;
 
var styles = StyleSheet.create({
    description: {
        fontSize: 20,
        backgroundColor: 'white'
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
});
 
class Search extends Component {
    render() {
        return (
        <View style={styles.container}>
            <Text style={styles.description}>
              Search Tab
            </Text>
        </View>
        );
    }
}
 
module.exports = Search;

上述程序除了文本組件中的文本都類似于 Featured.js 代碼。
在 index.ios.js 中剪切所有并粘貼在下邊。

'use strict';
 
var React = require('react-native');
var Featured = require('./Featured');
var Search = require('./Search');
 
var {
    AppRegistry,
    TabBarIOS,
    Component
   } = React;
 
class BookSearch extends Component {
 
    constructor(props) {
        super(props);
        this.state = {
            selectedTab: 'featured'
        };
    }
 
    render() {
        return (
            <TabBarIOS selectedTab={this.state.selectedTab}>
                <TabBarIOS.Item
                    selected={this.state.selectedTab === 'featured'}
                    icon={{uri:'featured'}}
                    onPress={() => {
                        this.setState({
                            selectedTab: 'featured'
                        });
                    }}>
                    <Featured/>
                </TabBarIOS.Item>
                <TabBarIOS.Item
                    selected={this.state.selectedTab === 'search'}
                    icon={{uri:'search'}}
                    onPress={() => {
                        this.setState({
                            selectedTab: 'search'
                        });
                    }}>
                    <Search/>
                </TabBarIOS.Item>
            </TabBarIOS>
        );
    }
}
 
AppRegistry.registerComponent('BookSearch', () => BookSearch);

這時我們需要從我們創建的文件中導出兩個模塊,并將他們分配給變量。在 class 內部,我們指定一個構造函數來為 class 設置一個狀態。這時我們要用組件的狀態函數。創建一個名為 selectedTab 的屬性,并將其值設置為 featured。我們將使用 featured 來確定哪個選項卡應該是主動的。然后設置默認選項卡。

在渲染()函數中我們使用 TabBarIOS 組件創建一個標簽欄。記得添加組件使用解構作業否則使用完全限定名稱,例如:React.TabBarIOS。

我們創建兩個標簽欄項目。我們為每個項目設立選中狀態并定義一個函數,當這個項目被選中時就會被命名。在 Featured 選項卡中,選擇設置為 true,如果 selectTab 狀態我們前邊定義的值為 feature,組件 selectedTab 是否等同于「搜索」。無論哪個選項卡被設置為 true 都將是活動選項卡。我們為標簽欄項目使用系統圖標。
注意我們使用我們的自定義組件標簽,就像任何其他組件,例如:因為我們需要相應的模塊,并將其分配到一個變量,你可以使用變量引入組件文件。這導致在 render() 函數的代碼組件的類包含就像是文件的一部分。順便說一下,我為各自變量的類名使用相同名稱的變量,但不一定要這樣,你可以盡可能的使用你喜歡的任何名稱。
當標簽欄被選中后,onPress 組件的屬性就會被回調函數定義。selectedTab 屬性的函數集值最終確定活動選項卡。
打開模擬器并按 Command-R 重新加載應用程序,你就會看到如下顯示。


如何用 React Native 創建一個iOS APP?(二)

添加 Navigation Bar

接下來,我們將向應用程序添加一個導航欄,給這個項目添加兩個以上的文件。他們將是根視圖導航堆棧的標簽。為 BookList.js 和SearchBooks.js 文件命名。
在 BookList.js 應用程序中添加以下代碼。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Component
   } = React;
 
var styles = StyleSheet.create({
 
});
 
class BookList extends Component {
    render() {
        return (
            <View>
        </View>             
        );
    }
}
 
module.exports = BookList;

在 SearchBooks.js 應用程序中添加以下代碼。

'use strict';
 
var React = require('react-native');
 
var {
    StyleSheet,
    View,
    Component
   } = React;
 
var styles = StyleSheet.create({
 
});
 
class SearchBooks extends Component {
    render() {
        return (
            <View>
        </View>             
        );
    }
}
 
module.exports = SearchBooks;

在兩個文件中,我們已經創建了一個帶有空白視圖的模塊然后輸出模塊。

修改 Featured.js 如圖:

'use strict';
 
var React = require('react-native');
var BookList = require('./BookList');
 
var {
    StyleSheet,
    NavigatorIOS,
    Component
   } = React;
 
var styles = StyleSheet.create({
    container: {
        flex: 1
    }
});
 
class Featured extends Component {
    render() {
        return (
            <NavigatorIOS
                style={styles.container}
                initialRoute={{
            title: 'Featured Books',
            component: BookList
            }}/>            
        );
    }
}
 
module.exports = Featured;

下一個 Search,js 修改如下所示:

'use strict';
 
var React = require('react-native');
var SearchBooks = require('./SearchBooks');
 
var {
    StyleSheet,
    NavigatorIOS,
    Component
   } = React;
 
var styles = StyleSheet.create({
    container: {
        flex: 1
    }
});
 
class Search extends Component {
    render() {
        return (
            <NavigatorIOS
                style={styles.container}
                initialRoute={{
            title: 'Search Books',
            component: SearchBooks
        }}/>            
        );
    }
}
 
module.exports = Search;

就像在 Featured.js,上面創建了一個導航控制器,設置其最初的路線并為它設置標題。

重新加載應用程序,你會看到如下所示:

獲取和顯示數據

現在我們要讀取數據了。首先我們要構建有假數據的視圖,然后使用來自 API 的真數據。
在 BookList.js 文件的頂部添加如下與其他變量的聲明。

var FAKE_BOOK_DATA = [
    {volumeInfo: {title: 'The Catcher in the Rye', authors: "J. D. Salinger", imageLinks: {thumbnail: 'http://books.google.com/books/content?id=PCDengEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api'}}}
];

修改解構任務直到顯示包含多個組件時我們才能使用。

var {
    Image,
    StyleSheet,
    Text,
    View,
    Component,
   } = React;

添加以下模版:

var styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
        padding: 10
    },
    thumbnail: {
        width: 53,
        height: 81,
        marginRight: 10
    },
    rightContainer: {
        flex: 1
    },
    title: {
        fontSize: 20,
        marginBottom: 8
    },
    author: {
        color: '#656565'
    }
});

然后修改如圖所示的 class:

class BookList extends Component {
    render() {
    var book = FAKE_BOOK_DATA[0];
        return (
            <View style={styles.container}>
                <Image source={{uri: book.volumeInfo.imageLinks.thumbnail}}
                            style={styles.thumbnail} />
                <View style={styles.rightContainer}>
                    <Text style={styles.title}>{book.volumeInfo.title}</Text>
                    <Text style={styles.author}>{book.volumeInfo.authors}</Text>
                </View>
            </View>
        );
    }
}

重新加載應用程序就會有如下顯示:

如何用 React Native 創建一個iOS APP?(二)

在以上代碼中,我們創建了一個類似于從 API 中調用的目標 JSON,我們通過這個目標為單獨的一本書創建了屬性和價值。在 class 文件中,我們使用假數據只為了得到第一個元素來填充我們的觀點。我們使用圖像組件把圖像加載成視圖。需要注意的是,我們要在樣式表中設置它的寬度和高度。如果你不指定圖像在樣式表中的尺寸,它就不會出現在視圖中。
我們指定一個 flexDirection 樣式:“行”容器。這將使帶有這種風格元素的孩子們的布局默認為水平而不是垂直。需要注意的是我們該如何包裝組件內的其他組件。在上面有帶有兩個孩子的主要容器物----一個圖像和一個視圖。這個視圖能顯示兩個屬于自己的孩子----即兩個文本組件。
首先是圖像布局,然后視圖(right Container)水平放置在它旁邊。我們指定一個 flex 模版:1rightContainer。這使得視圖占據了剩下的空間而不是圖像。如果你想要看到 flex 樣式的影響,那就添加以下 rightContainer。

backgroundColor: 'red'

重新加載應用程序,你就會看到 rightContainer 樣式的組件占用的空間。它占據整個空間而不被其他兄弟姐妹所占有。它并不拉伸屏幕,因為外容器有一些填充并且圖像有邊緣設置權利。

如何用 React Native 創建一個iOS APP?(二)

從 rightContainer 刪除 flex:1,重新加載應用程序。現在組件只占用足夠的可以適應其內容的空間。

如果你為 flex:2 的縮略圖和 rightContainer 設置一種風格,他們可能占據相同數量的空間,而且他們會有一個 2:2(或1:1)的寬度比。你可以指定任何值,所有可能的比例都會考慮在內。

如何用 React Native 創建一個iOS APP?(二)

你也可以嘗試不同的比率得到你喜歡的樣式。對于本教程,我們將從為rightContainer 添加一個紅色的背景這一步繼續深入。

未完待續

OneAPM Mobile Insight 以真實用戶體驗為度量標準進行 Crash 分析,監控網絡請求及網絡錯誤,提升用戶留存。訪問 OneAPM 官方網站感受更多應用性能優化體驗,想閱讀更多技術文章,請訪問 OneAPM 官方技術博客

本文轉自 OneAPM 官方博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容