说明
- 案例代码来自GitChat上李焱的《React Native 移动开发入门与实战》(要付费的)
- 适用对象:有一点React/js基础的
- 使用:你只需要创建新项目,把下边代码直接覆盖到App.js中即可运行。关键的方法说明都在注释中了。
代码
import React from 'react';
import { StyleSheet, Dimensions,ActivityIndicator, SectionList, FlatList, ScrollView, Alert, Button, Text, View, Image, TextInput} from 'react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
text: '',
isLoading: true,
imgs: [],
};
this.width = Dimensions.get('window').width;
this.height = Dimensions.get('window').height;
}
//生命周期
componentDidMount() {
this.searchHandler();
}
//从百度搜索图片
/*
ES2017 里的 async/await, 请求的固定写法:
async function getMoviesFromApi() {
try {
let response = await fetch('https://facebook.github.io/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch(error) {
console.error(error);
}
}
*/
async getImgsFromBaidu(query)
{
try {
//发送请求
let response = await fetch(`https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=111111&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=${query}&oq=${query}&rsp=-1`);
//获取到数据
let html = await response.text();
//处理数据
const start = "app.setData('imgData', ";
const end = ']}';
const startIndex = html.indexOf(start);
const endIndex = html.indexOf(end, startIndex);
const dataStr = html.slice(startIndex + start.length, endIndex + end.length);
const data = JSON.parse(dataStr.replace(/'/g, '"'));
//返回处理之后的数据信息
return data;
} catch (error) {
Alert.alert('getImgsFromBaidu-error:' + error)
console.error(error);
}
}
async searchHandler(query = '汉源湖') {
query = query || '汉源湖';
this.setState({ // 注意,如果直接修改 this.state.xxx= xxxx 是不行的, 不会渲染页面!
isLoading: true,
});
const imgResult = await this.getImgsFromBaidu(query); //表示等这个getImgsFromBaidu返回结果了再继续执行
// console.log(imgResult); //打印查看数据结构
const dataObj = imgResult.data; //根据'data'得到结果数组
console.log(dataObj); //打印查看数据结构
const imgsxxx = dataObj.map(e => {
delete e.base64; //删除base64这个节点数据
return e;
}).filter(e => !!e.thumbURL);
//套路, !!转boolean +转number ""+ 转string,这里是为了过滤thumbURL为空的模型,如果为空,则不保留
//filter: 返回值只要是弱等于== true/false
this.setState({
isLoading: false,
imgs: imgsxxx, //相当于 开始声明局部变量和constructor中相同: const imgs= dataObj.map(.... , 然后这里this.setState(...赋值直接写为 ({isLoading: false, imgs,})
})
}
//按钮点击事件
buttonHandler = () => {
this.searchHandler(this.state.text);
}
render() {
return (
<View>
<ScrollView>
<View style={{ height :40}} />
<View>
<View style={{ flex:1, flexDirection: 'row', justifyContent: 'center',}}>
<TextInput style={{width: 300, height: 40, borderColor: 'black', borderWidth: 1,}}
placeholder="汉源湖"
onChangeText={text => this.setState({text})} // 相当于: onChangeText={textxxx => this.setState({text: textxxx})},这里是输入框输入的结果赋值给state
/>
<Button
onPress={this.buttonHandler}
title="搜索"
color="#841584"
/>
</View>
</View>
{
//这部分是动态变化的, 如果是刷新状态的话,那么就执行呈现转圈ActivityIndicator; 如果是刷新完成,那么则显示FlatList列表
this.state.isLoading ? <ActivityIndicator />
:
<FlatList
data={this.state.imgs}
renderItem={({item}) => {
const img = item;
if(!img.thumbURL) {
return null;
}
return <Image
style={{width: this.width, height: this.width*img.height/img.width}}
source={{uri: img.thumbURL}}
/>
}}
keyExtractor={(item, index) => {
return item.thumbURL;
}}
/>
}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
},
});
交流
希望能和大家交流技术
Blog:http://www.lilongcnc.cc