粗糙的效果图:
json格式:
需要添加React Navigation的依赖 官网
在当前项目根目录打开命令行,安装运行如下命令
yarn add react-navigation
还需要安装react-native-gesture-handler
yarn add react-native-gesture-handler
完成后连接本机依赖项
react-native link react-native-gesture-handler
针对android还需要更改MainActivity的代码,而ios并不用。难受
添加如下信息
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
因为我们已经安装了react-native-gesture-handler依赖,所以编译后直接导包就好。
流程:在网络请求之前一直显示加载的进图条,当网络响应到数据的时候把进度条隐藏,(进度条隐藏后还是占用了屏幕位置,待解决),用FlatList展示了数据,点击每一条数据都会跳转到一个新的界面,并把当前点击条目的数据携带过去,导航条是用react navigation实现的。
React Navigation
在根目录文件中引入了两个js文件,这两个文件就是两个页面
import Video from './Video';
import Detailed from './Detailed'
通过createStackNavigator创建了导航路线,并定义了初始界面。
const AppNavigator = createStackNavigator(
{
Home: Video,
Details: Detailed
},
{
initialRouteName: "Home"
}
);
export default createAppContainer(AppNavigator);
给Video页面设置title
static navigationOptions = {
title: 'Video',
};
Detailed页面也是同理
static navigationOptions = {
title: 'Detailed',
};
这时候只是定义了两个页面,并不能跳转,往下看。
Fetch
在Video.js中,在componentDidMount函数中进行的网络请求调用
this.state = {
isShowActivityIndicator: true,
data: null,
}
...
fetch("https://raw.githubusercontent.com/facebook/react-native/0.51-stable/docs/MoviesExample.json")
.then((response) => response.json())
.then((responseData) => {
this.setState({
isShowActivityIndicator: false,
//这里的data状态是用作于FlatList,所以必须是一个数组。
data: responseData.movies,
});
});
FlatList
长列表数据,可以上下滑动,不会一次加载所有数据。用到属性如下
data:数据源,肯定要数组形式
renderItem:逐个解析数据,返回组件渲染。
<FlatList data={this.state.data}
renderItem={({item, index}) => this.renderItem(item, index)}/>
这里把renderitem属性的箭头函数的后半部分写成了一个函数,也就是每一条数据的渲染。
renderItem(item, index) {
return (
<TouchableNativeFeedback onPress={this.onPressButton.bind(this,item,index)}>
<View style={styles.itemV}>
<Image style={styles.imagV}
source={{uri: item.posters.thumbnail}}></Image>
<View style={styles.itemV1}>
<Text> {item.title} </Text>
<Text> {item.id} </Text>
</View>
</View>
</TouchableNativeFeedback>
);
}
而要想给每一条数据都添加点击事件,就在这个item的最外层添加触摸事件,并且绑定了一条数据。
onPressButton(item,index){
this.props.navigation.navigate('Details',{
index:index,
itemid:item.id,
itemTitle:item.title,
itemUri:item.posters.thumbnail,
})
}
跳转到’Details’页面,这个页面是在一开始就声明了,就是通过 this.props.navigation.navigate(‘Details’)进行跳转的,如果要携带参数就需要以{ k:v}的形式添加第二个参数。
render() {
const {navigation} = this.props;
const index = navigation.getParam('index', 'no');
const itemid = navigation.getParam('itemid', 'no');
const itemTitle = navigation.getParam('itemTitle', 'no');
const itemUri = navigation.getParam('itemUri', 'no');
return (
<View style={{flex: 1, alignItems: "center", justifyContent: "center"}}>
<Text>{JSON.stringify(index)}</Text>
<Text>{JSON.stringify(itemid)}</Text>
<Text>{JSON.stringify(itemTitle)}</Text>
<Text>{JSON.stringify(itemUri)}</Text>
</View>
);
}
const index =navigation.getParam(‘index’,‘no’)第二个参数是当index为key,取不到值时index就会为’no’