React Native 开发豆瓣评分(八)首页开发
首页完成效果展示:

一、开发占位图组件
在没有数据的时候使用占位图替代 items 的位置。
在 components 目录里创建 moviesItemPlaceholder.js
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { px } from '../utils/device';
export default class MoviesItemPlaceholder extends Component {
render() {
const arr = [1, 2, 3, 4];
return (
<View style={styles.page}>
{arr.map((index) => (
<View style={styles.placeholder} key={index}>
<View style={styles.img} />
<View style={styles.title} />
<View style={styles.rate} />
</View>
))}
</View>
)
}
}
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
paddingLeft: px(30)
},
placeholder: {
width: px(160),
marginRight: px(16)
},
img: {
width: px(160),
height: px(224),
overflow: 'hidden',
borderRadius: px(8),
backgroundColor: '#f8f8f8'
},
title: {
marginTop: px(20),
backgroundColor: '#f8f8f8',
height: px(30),
width: px(130),
overflow: 'hidden',
borderRadius: px(8)
},
rate: {
marginTop: px(16),
backgroundColor: '#f8f8f8',
height: px(24),
width: px(130),
overflow: 'hidden',
borderRadius: px(8)
}
});
二、首頁数据请求
使用 postman 之类的工具可以看到,首页接口返回的数据字段大致一样,数据均在 subject_collection_items 字段里,可以疯转一个方法量来请求数据。
var items = ['showing', 'hot', 'tv', 'variety', 'book', 'music'];
items.forEach(type => {
this.getList(type);
});
getList = (type) => {
ajax(type, {
start: 0,
count: 9
}).then(value => {
let state = {}
state[type] = value.subject_collection_items;
this.setState(state);
})
}
首页页面展示
纵向滑动,使用 ScrollView 组件;横向滑动,使用 FlatList 组件,FlatList 组件的 ListEmptyComponent 表示没有数据时显示的组件,在这里放置占位图组件;
import React from "react";
import { View, Text, StatusBar, StyleSheet, ScrollView, FlatList, TouchableWithoutFeedback } from "react-native";
import { connect } from 'react-redux';
import ajax from "../utils/ajax";
import Header from '../components/header';
import ItemsHeader from '../components/itemsHeader';
import MoviesItem from '../components/moviesItem';
import MoviesItemPlaceholder from '../components/moviesItemPlaceholder';
import Icon from 'react-native-vector-icons/AntDesign';
import { px } from "../utils/device";
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
showing: [],
hot: [],
tv: [],
variety: [],
book: [],
music: [],
}
var items = ['showing', 'hot', 'tv', 'variety', 'book', 'music'];
items.forEach(type => {
this.getList(type);
});
}
getList = (type) => {
ajax(type, {
start: 0,
count: 9
}).then(value => {
let state = {}
state[type] = value.subject_collection_items;
this.setState(state);
})
}
render() {
const { dispatch, value, navigation } = this.props;
const { showing, hot, tv, variety, book, music } = this.state;
const sections = [
{ title: '影院热映', data: showing, type: 'showing' },
{ title: '豆瓣热门', data: hot, type: 'hot' },
{ title: '近期热门剧集', data: tv, type: 'tv' },
{ title: '近期热门综艺节目', data: variety, type: 'variety' },
{ title: '畅销图书', data: book, type: 'book' },
{ title: '热门单曲榜', data: music, type: 'music' }
]
return (
<View style={styles.page}>
<Header showBack={false} title='豆瓣评分' backgroundColor='#00b600' color='#fff' />
<ScrollView>
<View style={styles.search}>
<TouchableWithoutFeedback onPress={() => alert('search')}>
<View style={styles.searchView}>
<Icon name='search1' size={px(30)} color='#ccc' />
<Text style={styles.searchText}>搜索</Text>
</View>
</TouchableWithoutFeedback>
</View>
{sections.map((list, index) => (
<View key={index} style={styles.list}>
<ItemsHeader title={list.title} onPress={() => navigation.push('List', { data: list })} />
<FlatList
horizontal={true}
data={list.data}
keyExtractor={(item, index) => 'item' + index}
ListEmptyComponent={() => <MoviesItemPlaceholder />}
renderItem={({ item, index }) => (
<View style={{ marginRight: index !== showing.length - 1 ? px(16) : px(30), marginLeft: index === 0 ? px(30) : 0 }}>
<MoviesItem data={item} />
</View>
)}
/>
</View>
))}
</ScrollView>
</View>
);
}
}
const select = (store) => {
return {
value: store.num.value,
}
}
export default connect(select)(Home);
const styles = StyleSheet.create({
page: {
flex: 1,
backgroundColor: '#fff'
},
search: {
backgroundColor: '#00b600',
height: px(80),
alignItems: 'center',
justifyContent: 'center'
},
searchView: {
height: px(50),
width: px(710),
borderRadius: px(8),
backgroundColor: '#fff',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center'
},
searchText: {
fontSize: px(26),
color: '#ccc',
marginLeft: px(6)
},
list: {
marginBottom: px(30)
}
});
四、缓存列表数据
当处于弱网环境时,打开应用,可能会显示很久的占位图,此时我们可以将列表数据缓存至本地,每次进入应用先展示本地缓存的数据,然后请求数据,替换本地数据。
此时,就可以使用 redux 了。
编译 reducer
为了目录整清晰点(让 redux 相关的代码文件都存储于 store 目录下),将 src 目录下的 reducer 目录移动到 store 目录下,并在 reducer 目录创建 list.js。
const initList = {
showing: [],
hot: [],
tv: [],
variety: [],
book: [],
music: []
}
const setListState = (state = initList, action) => {
switch (action.type) {
case 'showing':
return {
...state,
showing: action.data
}
case 'hot':
return {
...state,
hot: action.data
}
case 'tv':
return {
...state,
tv: action.data
}
case 'variety':
return {
...state,
showing: action.data
}
case 'book':
return {
...state,
book: action.data
}
case 'music':
return {
...state,
music: action.data
}
default:
return state;
}
}
export default setListState;
在 reducer 的 index.js 中导入 setListState;
...
import setListState from './list';
...
export default combineReducers({
...
list: setListState
...
});
修改 store/index.js 的路径引入
import reducer from './reducer';
编辑 action
将之前src下的 action 目录删除,在 store 目录下创建 action.js。
export function login(data) {
return {
type: 'login',
data
}
}
export function logout(data) {
return {
type: 'logout',
data
}
}
// set 首页列表数据
export function setShowing(data) {
return {
type: 'showing',
data
}
}
export function setHot(data) {
return {
type: 'hot',
data
}
}
export function setTv(data) {
return {
type: 'tv',
data
}
}
export function setVariety(data) {
return {
type: 'variety',
data
}
}
export function setBook(data) {
return {
type: 'book',
data
}
}
export function setMusic(data) {
return {
type: 'music',
data
}
}
编辑首页
导入修改 store 的方法:
import { setShowing, setHot, setTv, setVariety, setBook, setMusic } from '../store/action';
页面获取 store 存储的数据:
const select = (store) => {
return {
showing: store.list.showing,
hot: store.list.hot,
tv: store.list.tv,
variety: store.list.variety,
book: store.list.book,
music: store.list.music
}
}
export default connect(select)(Home);
页面获取数据时,改变 store 里的数据
由于需要 save 数据,所以前面创建的 getList 和传入的 items 需要做一些改变:
...
var items = [
{ type: 'showing', save: setShowing },
{ type: 'hot', save: setHot },
{ type: 'tv', save: setTv },
{ type: 'variety', save: setVariety },
{ type: 'book', save: setBook },
{ type: 'music', save: setmusic },
]
items.forEach(item => {
this.getList(item);
});
...
getList = (item) => {
ajax(item.type, {
start: 0,
count: 9
}).then(value => {
this.props.dispatch(item.save(value.subject_collection_items));
})
}
修改 render 里的获取数据方式:
render(){
const { dispatch, value, navigation, showing, hot, tv, variety, book, music } = this.props;
...
}
至此,首页算是开发完了。
React Native 开发豆瓣评分(八)首页开发的更多相关文章
- React Native从零到一搭建开发环境
React Native从零到一搭建开发环境 ReactNative环境搭建 安装Homebrew 安装rvm 安装nvm 安装node 安装react-native-cli 安装watchman i ...
- React Native 开发豆瓣评分(五)屏幕适配方案
前言 React Native 是以实际像素 dp 为单位的,这导致在不同分辨率的屏幕会有不一样的显示情况. 在原生 Android 中,可以根据不同的分辨率添加不同的样式目录,以解决不同分辨率的问题 ...
- React Native 开发豆瓣评分(一)环境搭建&配置模拟器
详细可参考 官方文档,这里进记录一些重要过程. 安装环境 下载 Android Studio 选择 Custom 进行安装: Android SDK Android SDK Platform Perf ...
- React Native 开发豆瓣评分(四)集中管理 fetch 数据请求
豆瓣评分的API接口 接口是从网上查找的,看样子应该是微信小程序里面扣出来的(ua 里面有 wechatdevtools) 接口都需要设置apiKey(054022eaeae0b00e0fc068c0 ...
- React Native 开发豆瓣评分(三)集成 Redux
什么是 redux redux 是一个用于管理 js 应用状态(state)的容器.比如组件 A 发生了变化,组件 B 要同时做出响应.常见的应用场景就是用户的登录退出操作:未登录状态,个人中心显示登 ...
- React Native for Android on Windows 配置开发安装总结
配置开发安装总结(由于当前react-native更新较快,目前是针对2015年11月底时的reacti-native android for windows版本,有些内容可能过时) 官方的安装指导在 ...
- React Native学习(一)——搭建开发环境
第一次接触React Native,首先搭建环境,过程还算顺利,不过也遇到了些问题,这里简单记录下来.中文官网(http://reactnative.cn/docs/0.47/getting-star ...
- React Native 开发豆瓣评分(七)首页组件开发
首页内容拆分 看效果图,首页由热门影院.豆瓣热门.热门影视等列表组成,每个列表又由头加横向滑动的 电影海报列表构成. 所以可以先把页面的电影海报.评分.列表头做成组件,然后在使用 ScrollView ...
- React Native 开发豆瓣评分(二)路由配置
路由管理使用官方推荐的 React Navigation; 配置环境 安装相关依赖 yarn add react-navigation react-native-gesture-handler Lin ...
随机推荐
- 范仁义html+css课程---3、图片和超链接
范仁义html+css课程---3.图片和超链接 一.总结 一句话总结: img标签是图片标签,定义 HTML 页面中的图像 a标签是超链接标签,用于从一个页面链接到另一个页面. 1.img标签要点? ...
- win10回收站右键有2个“CCleaner”怎么删除
win10回收站右键有2个"CCleaner"怎么删除? win10系统安装最新的CCleaner后遇到了这样子的问题:右击回收站有两个关于CCleaner的乱码,卸载CCle ...
- 运维笔记--linux下忘记mysql root密码
补充链接:Windows下忘记密码处理: https://www.cnblogs.com/hellojesson/p/5972950.html 场景描述: Linux环境下忘记 root 密码, 1. ...
- python爬虫案例:使用XPath爬网页图片
用XPath来做一个简单的爬虫,尝试爬取某个贴吧里的所有帖子,并且将该这个帖子里每个楼层发布的图片下载到本地. # -*- coding:utf-8 -*- import urllib import ...
- FactorVAE论文学习-1
Disentangling by Factorising 我们定义和解决了从变量的独立因素生成的数据的解耦表征的无监督学习问题.我们提出了FactorVAE方法,通过鼓励表征的分布因素化且在维度上独立 ...
- asp.net core mvc 读取配置文件appsettings.json
上一篇我们将了读取自定义配置文件.这篇我们讲一下asp.net core mvc里读取自带的配置文件 appsettings.json 首先创建个asp.net core mvc项目,项目里有Prog ...
- html页面自适应宽度
html页面实现响应式的方式有很多,本篇介绍懒人必备一招见效的方法. 在head标签中加入 <meta name="viewport" content="width ...
- QT源码分析:QTcpServer
最近在看有关IO复用方面的内容,自己也用标准c++库实现了select模型.iocp模型.poll模型.回过头来很想了解QT的socket是基于什么模型来实现的,所以看了QT关于TcpServer实现 ...
- 托马斯·贝叶斯 (Thomas Bayes)
朴素贝叶斯 Day15,开始学习朴素贝叶斯,先了解一下贝爷,以示敬意. 托马斯·贝叶斯 (Thomas Bayes),英国神学家.数学家.数理统计学家和哲学家,1702年出生于英国伦敦,做过神甫: ...
- 机试指南第二章-经典入门-Hash的应用自解
Hash的应用: Hash即散列,不像数据结构与算法中讲的各种Hash方法和冲突处理等过多的阐述,以下主要介绍Hash在机试试题解答中的作用. 例2.5 统计同成绩学生人数 Hash解法AC代码:(一 ...