这个项目的话,倒是可以做一个支架页面,就是你需要什么东西,你就可以在里面加,不过也是比较难的地方
就是数据流,数据处理的部分。react可以处理数据的方式很多,没有见过类似于古老的vue时候可以使用的
$.http(),我觉得实现功能是第一步,至于技术的高低,哎,捂脸
【博客后文把前面说的都否认了,talk is cheap,show me the code 】
项目地址为:https://github.com/XinmengSiRan/douban-movies-react-native
先看页面
//index.js
/** @format */import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';AppRegistry.registerComponent(appName, () => App);
//App.js
//定义了根App.js
/*** Sample React Native App* https://github.com/facebook/react-native** @format* @flow*/import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';import AppContainer from './src';type Props = {navigation: any
};
export default class App extends Component <Props>{render() {return (<AppContainer />);}
}
//src/index.js
//定义底部和切换页面
import React, { Component } from 'react';
import { Dimensions, AppRegistry, StyleSheet, Text, View, ButtonTouchableOpacity, Image, ScrollView, FlatList, ActivityIndicator} from 'react-native';
import { createAppContainer, createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import { createStore} from 'redux';
import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from 'react-native-scrollable-tab-view';import PlayList from './components/PlayList';
import Search from './components/Search';
import My from './components/My';
import Icon from 'react-native-vector-icons/Ionicons';/*为了注释调试提醒*/
console.ignoredYellowBox = ['Remote debugger'];
const BottomTabNavigator = createBottomTabNavigator({热映: {//通过createStackNavigator中的值来切换页面screen: createStackNavigator({PlayList}),navigationOptions: {tabBarLabel: '热映',tabBarIcon: ({tintColor}) => (<Icon name="ios-tv" size={20} color={tintColor} />)}},找片: {screen: createStackNavigator({Search}),navigationOptions: {tabBarLabel: '找片',tabBarIcon: ({tintColor}) => (<Icon name="ios-eye" size={20} color={tintColor} />)}},我的: {screen: createStackNavigator({My}),navigationOptions: {tabBarLabel: '我的',tabBarIcon: ({tintColor}) => (<Icon name="ios-person" size={20} color={tintColor} />)}}
}, {tabBarPosition: 'bottom',tabBarOptions: {activeTintColor: '#494949',inactiveTintColor: '#999999',labelStyle: {fontSize: 12,marginBottom: 5},style: {borderTopWidth: 1,borderTopColor: '#eeeeee',height: 50,backgroundColor: '#ffffff'}}
});
//切换的底部页面
const AppContainer = createAppContainer(BottomTabNavigator);export default AppContainer;
//其实我比较好奇这种写法,一下子组件都引进来了,会不会首页太大很卡的问题
//src/components/PlayList.js
import React, { Component } from 'react';
import { StyleSheet, Dimensions, Text, View, Button, FlatList } from 'react-native';
import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
import { createAppContainer, createStackNavigator} from 'react-navigation';
import HotList from './HotList';
import SoonList from './SoonList';
export default class PlayList extends Component {
//这里定义的头部
static navigationOptions = {
title: 'Home'
};
render() {return (<View style={styles.container}><ScrollableTabViewrenderTabBar={() => <DefaultTabBar/> }tabBarUnderlineStyle={{backgroundColor: '#000',height: 2}}tabBarBackgroundColor='#fff'tabBarActiveTextColor='#000'tabBarInactiveTextColor='#959595'tabBarTextStyle={{ fontSize: 16 }}locked={false}><View tabLabel='正在热映' style={{marginBottom:50}}><HotList navigation={this.props.navigation}></HotList></View><View tabLabel='即将上映' style={{marginBottom:50}}><SoonList navigation={this.props.navigation}></SoonList></View></ScrollableTabView></View>);
}
}
//在页面里面判断的是不是iphonex做不做别的适配
const { width, height } = Dimensions.get('window');
const IS_IPHONE_X_SERIES = () => {
if (height == 812 || height == 896) {
return true;
}else{
return false;
}
}
const styles = StyleSheet.create({
container: {
width: width,
height: IS_IPHONE_X_SERIES ? (height - 88 - 34) : (height - 64),
paddingTop: 10,
backgroundColor: '#fff'
}
});
//里面有两个组件,代表的两个页面我一开始以为页面真的就是架子,可是分析代码发现里面是有数据请求的 很惊讶阿,这种bug我不会调,先放代码
js
//src/components/HotList.js
import React, { Component } from 'react';
import {
ActivityIndicator,
StyleSheet,
Dimensions,
Image,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
Button,
FlatList
} from 'react-native';
import Star from './Star';
export default class HotList extends Component {
constructor(props) {
super(props);
this.state = {
ready: true,
refreshing: false,
data: []
}
}
componentDidMount() {this._fetchData();
}handleOnPress = () => {}_fetchData = () => {fetch('https://api.douban.com/v2/movie/in_theaters').then((response) => {this.setState({refreshing: false});return response.json();}).then((responseJson) => {console.log('response', responseJson);const dataArr = responseJson.subjects;this.setState({ready: false,refreshing: false,data: dataArr});}).catch((error) => {console.error(error);});
}_refreshData = () => {this.setState({refreshing: true});this._fetchData();
}
render() {const {navigate} = this.props.navigation;const {data} = this.state;return (<View style={styles.container}>{this.state.ready ? <ActivityIndicator size='large' style={styles.loadding}/>: <FlatListdata={data}onRefresh={this._refreshData}refreshing={this.state.refreshing}keyExtractor={(item, index ) => index+item}renderItem={({item}) => {return (<TouchableOpacitystyle={styles.item}onPress={this.handleOnPress}><View style={{flex: 1,}}><Image source={{uri: item.images.large}}style={styles.image} /></View><View style={{flex: 2, alignItems: 'flex-start', paddingLeft: 5}}><Text style={styles.title}>{item.title}</Text><View style={styles.star}><Star value={item.rating}></Star></View><Text style={styles.smallFont}>导演:{item.directors[0].name}</Text><Text style={styles.smallFont}>主演:{item.casts.map((v) => v.name).join('/')}</Text></View><View style={{alignItems: 'flex-end'}}><Text style={[styles.smallFont, styles.redFont]}>{(item.collect_count / 10000.0 > 1) ? (item.collect_count / 10000.0).toFixed(1) + '万人看过': item.collect_count + '人看过'}</Text><TouchableOpacitystyle={styles.buyTicket}><Text style={styles.redFont}>购票</Text></TouchableOpacity></View></TouchableOpacity>);}} />} </View>);
}
}
const styles = StyleSheet.create({
loadding: {
marginTop: 30
},
item: {
height: 140,
paddingLeft: 18,
paddingRight: 18,
paddingTop: 10,
paddingBottom: 10,
flexDirection: 'row',
alignItems: 'center',
borderBottomWidth: 1,
borderBottomColor: '#eeeeee',
},
image: {width: 80,height: 120,
},
title: {fontSize: 16,fontWeight: 'bold'
},
smallFont: {fontSize: 12,lineHeight: 20,color: '#A6A6A6'
},
buyTicket: {width: 60,height: 30,marginTop: 5,borderRadius: 5,borderWidth: 1,borderColor:'#FF4E65',justifyContent: 'center',alignItems: 'center'
},
redFont: {color: '#FF4E65',
},
star: {marginTop: 10,marginBottom: 10
}
});js
//src/components/SoonList.js
import React, { Component } from 'react';
import {
ActivityIndicator,
StyleSheet,
Image,
Text,
TouchableOpacity,
View,
FlatList,
} from 'react-native';
import Star from './Star';
export default class SoonList extends Component {
constructor(props) {
super(props);
this.state = {
ready: true,
refreshing: false,
data: []
}
}
componentDidMount() {this._fetchData();
}handleOnPress = () => {}_fetchData = () => {fetch('https://api.douban.com/v2/movie/coming_soon').then((response => {this.setState({refreshing: false});return response.json();})).then((responseJson) => {console.log(responseJson);const dataArr = responseJson.subjects;this.setState({ready: false,refreshing: false,data: dataArr});}).catch((eror) => {console.error(error);});
}_refreshData = () => {this.setState({refreshing: true});this._fetchData();
}renderMovieItem = (item) => {return (<TouchableOpacitystyle={styles.item}onPress={this.handleOnPress}><View style={{flex: 1,}}><Image source={{uri: item.images.large}}style={styles.image} /></View><View style={{flex: 2, alignItems: 'flex-start', paddingLeft: 5}}><Text style={styles.title}>{item.title}</Text><View style={styles.star}><Star value={item.rating}></Star></View><Text style={styles.smallFont}>导演:{item.directors[0].name}</Text><Text style={styles.smallFont}>主演:{item.casts.map((v) => v.name).join('/')}</Text></View><View style={{alignItems: 'flex-end'}}><Text style={[styles.smallFont, styles.yellowFont]}>{(item.collect_count / 10000.0 > 1) ? (item.collect_count / 10000.0).toFixed(1) + '万人想看': item.collect_count + '人想看'}</Text><TouchableOpacitystyle={styles.buyTicket}><Text style={styles.yellowFont}>想看</Text></TouchableOpacity></View></TouchableOpacity>);
}render() {const {data} = this.state;const {navigate} = this.props.navigation;return (<View>{this.state.ready? <ActivityIndicator size='large' style={styles.loadding} />: <FlatListdata={data}onRefresh={this._refreshData}refreshing={this.state.refreshing}keyExtractor={(item, index) => index + item}renderItem={({item}) => this.renderMovieItem(item)} />}</View>);
}
}
const styles = StyleSheet.create({
loadding: {
marginTop: 30
},
item: {
height: 140,
paddingLeft: 18,
paddingRight: 18,
paddingTop: 10,
paddingBottom: 10,
flexDirection: 'row',
alignItems: 'center',
borderBottomWidth: 1,
borderBottomColor: '#eeeeee',
},
image: {width: 80,height: 120,
},
title: {fontSize: 16,fontWeight: 'bold'
},
smallFont: {fontSize: 12,lineHeight: 20,color: '#A6A6A6'
},
buyTicket: {width: 60,height: 30,marginTop: 5,borderRadius: 5,borderWidth: 1,borderColor:'#EFA300',justifyContent: 'center',alignItems: 'center'
},
yellowFont: {color: '#EFA300'
},
star: {marginTop: 10,marginBottom: 10
}
});
js
//src/components/Search.js
import React, { Component } from 'react';
import { Dimensions, Text, View, Button, FlatList } from 'react-native';
import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
import { createAppContainer, createStackNavigator} from 'react-navigation';
const { width, height } = Dimensions.get('window');
export default class Search extends Component {
static navigationOptions = {
title: 'Search',
};
render() {const { navigate } = this.props.navigation;return (<View><Text>找片</Text></View>);
}
}
```
//src/components/My.js
import React, { Component } from 'react';
import { Dimensions, Text, View, Button, FlatList } from 'react-native';
import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
import { createAppContainer, createStackNavigator} from 'react-navigation';const { width, height } = Dimensions.get('window');export default class My extends Component {static navigationOptions = {title: 'My'};render() {const { navigate } = this.props.navigation;return (<View><Text>我的</Text></View>);}
}
时时当勉励,岁月不待人,加油~~~加油~~~