React Native 实例 - BBC新闻客户端
关于 主要技术
本文源码的GitHub下载地址 配置项目初始化项目WclBBCNews,修改 "dependencies": {
"react": "^0.14.8","react-native": "^0.24.1","htmlparser": "^1.7.7","moment": "^2.11.1","react-native-linear-gradient": "^1.4.0","react-native-video": "^0.6.1" }
初始化主模块 render() {
return (
<NavigatorIOS style={{flex:1}} translucent={false} barTintColor={'#BB1919'} titleTextColor={'white'} tintColor={'white'} initialRoute={{ component: Feed,title: "Feed",passProps: {} }}/> ); }
渲染使用动态加载组件,StatusBar使用浅色样式. _renderScene(route,navigator) {
var Component = route.component;
StatusBar.setBarStyle('light-content');
return (
<Component {...route.props} changeNavBarHeight={this.changeNavBarHeight} navigator={navigator} route={route}/> ); }
新闻列表Feed页面,主要以列表形式,即 render() {
// 未加载完成时,调用加载页面
if (!this.state.loaded) {
return this._renderLoading();
}
// ...
}
_renderLoading() {
return (
<View style={{flexDirection: 'row',justifyContent: 'center',flex: 1}}> <ActivityIndicatorIOS animating={this.state.isAnimating} style={{height: 80}} size="large"/> </View> ); }
加载完成后,调用 return (
<ListView testID={"Feed Screen"} dataSource={this.state.dataSource} renderRow={this._renderStories.bind(this)} style={{backgroundColor: '#eee'}} contentInset={{top:0, left:0,bottom: 64,right: 0}} scrollEventThrottle={200} {...this.props} refreshControl={ <RefreshControl refreshing={this.state.isRefreshing} onRefresh={this._fetchData.bind(this)} tintColor='#BB1919' title="Loading..." progressBackgroundColor="#FFFF00" />} /> );
每一行使用 _renderStories(story) {
return (
<Story story={story} navigator={this.props.navigator}/> ); }
启动页面的时候,使用 componentDidMount() {
this._fetchData();
}
通过访问BBC的网络请求,异步获取数据. 使用 _fetchData() {
this.setState({isRefreshing: true});
fetch(`http://trevor-producer-cdn.api.bbci.co.uk/content${this.props.collection || '/cps/news/world'}`)
.then((response) => response.json())
.then((responseData) => this._filterNews(responseData.relations))
.then((newItems) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newItems),loaded: true,isRefreshing: false,isAnimating: false
})
}).done();
}
列表项提供分类显示功能,点击类别,可以重新加载所选类型的新闻,把 _pressedCollection(collection) {
this.props.navigator.push({
component: Feed,title: collection.content.name,passProps: {
collection: collection.content.id,navigator: this.props.navigator
}
});
}
点击列表项,跳转至详情页面 _pressedStory(story) {
this.props.navigator.push({
component: StoryDetail,title: this._truncateTitle(story.content.name),passProps: {story,navigator: this.props.navigator}
});
}
新闻详情主要是解析HTML页面,加载并显示,除了文字之外,会显示图片视频超链接等样式. 渲染使用动态元素,状态 render() {
if (this.state.loading) {
return (
<Text>Loading</Text> ); } return this.state.elements; }
页面启动时,加载数据. 在 componentDidMount() {
this._fetchStoryData(
// media表示视频或图片.
(result,media) => {
const rootElement = result.find(item => {
return item.name === 'body';
});
XMLToReactMap.createReactElementsWithXMLRoot(rootElement,media)
.then(array => {
var scroll = React.createElement(ScrollView,{
contentInset: {top: 0,left: 0,bottom: 64,right: 0},style: {flex: 1,flexDirection: 'column',backgroundColor: 'white'},accessibilityLabel: "Story Detail"
},array);
this.setState({loading: false,elements: scroll});
});
}
);
}
处理数据,使用 _fetchStoryData(cb) {
// 提取数据,转换JSON格式,图片过滤,视频过滤,组合relations,解析.
fetch(`http://trevor-producer-cdn.api.bbci.co.uk/content${this.props.story.content.id}`)
.then((response) => response.json())
.then((responseData) => {
const images = responseData.relations.filter(item => {
return item.primaryType === 'bbc.mobile.news.image';
});
const videos = responseData.relations.filter(item => {
return item.primaryType === 'bbc.mobile.news.video';
});
const relations = {images,videos};
this._parseXMLBody(responseData.body,(result) => {
cb(result,relations);
});
}).done();
}
使用 _parseXMLBody(body,cb) {
var handler = new Tautologistics.NodeHtmlParser.DefaultHandler(
function (error,dom) {
cb(dom)
},{enforceEmptyTags: false,ignoreWhitespace: true});
var parser = new Tautologistics.NodeHtmlParser.Parser(handler);
parser.parseComplete(body);
}
XML解析类
通过编写新闻类应用,学习使用网络请求和解析HTML格式的文本. 多编码多思考,不断学习, OK,that’s all! Enjoy it!
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |