首页完成效果展示:

一、开发占位图组件

在没有数据的时候使用占位图替代 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 开发豆瓣评分(八)首页开发的更多相关文章

  1. React Native从零到一搭建开发环境

    React Native从零到一搭建开发环境 ReactNative环境搭建 安装Homebrew 安装rvm 安装nvm 安装node 安装react-native-cli 安装watchman i ...

  2. React Native 开发豆瓣评分(五)屏幕适配方案

    前言 React Native 是以实际像素 dp 为单位的,这导致在不同分辨率的屏幕会有不一样的显示情况. 在原生 Android 中,可以根据不同的分辨率添加不同的样式目录,以解决不同分辨率的问题 ...

  3. React Native 开发豆瓣评分(一)环境搭建&配置模拟器

    详细可参考 官方文档,这里进记录一些重要过程. 安装环境 下载 Android Studio 选择 Custom 进行安装: Android SDK Android SDK Platform Perf ...

  4. React Native 开发豆瓣评分(四)集中管理 fetch 数据请求

    豆瓣评分的API接口 接口是从网上查找的,看样子应该是微信小程序里面扣出来的(ua 里面有 wechatdevtools) 接口都需要设置apiKey(054022eaeae0b00e0fc068c0 ...

  5. React Native 开发豆瓣评分(三)集成 Redux

    什么是 redux redux 是一个用于管理 js 应用状态(state)的容器.比如组件 A 发生了变化,组件 B 要同时做出响应.常见的应用场景就是用户的登录退出操作:未登录状态,个人中心显示登 ...

  6. React Native for Android on Windows 配置开发安装总结

    配置开发安装总结(由于当前react-native更新较快,目前是针对2015年11月底时的reacti-native android for windows版本,有些内容可能过时) 官方的安装指导在 ...

  7. React Native学习(一)——搭建开发环境

    第一次接触React Native,首先搭建环境,过程还算顺利,不过也遇到了些问题,这里简单记录下来.中文官网(http://reactnative.cn/docs/0.47/getting-star ...

  8. React Native 开发豆瓣评分(七)首页组件开发

    首页内容拆分 看效果图,首页由热门影院.豆瓣热门.热门影视等列表组成,每个列表又由头加横向滑动的 电影海报列表构成. 所以可以先把页面的电影海报.评分.列表头做成组件,然后在使用 ScrollView ...

  9. React Native 开发豆瓣评分(二)路由配置

    路由管理使用官方推荐的 React Navigation; 配置环境 安装相关依赖 yarn add react-navigation react-native-gesture-handler Lin ...

随机推荐

  1. Python 拼接字符串的几种方式

    在学习Python(3x)的过程中,在拼接字符串的时候遇到了些问题,所以抽点时间整理一下Python 拼接字符串的几种方式. 方式1,使用加号(+)连接,使用加号连接各个变量或者元素必须是字符串类型( ...

  2. semi-join子查询优化 -- FirstMatch策略

    FirstMatch执行semi-join子查询的一种策略. 类似于MySQL 5.x中如何执行in.exists子查询. 让我们以搜索拥有大城市的国家为例: select * from Countr ...

  3. easyui datagrid怎么动态获取表头的列名及显示名称

    说明:目前使用easyui combobox多选属性,绑定的数据源是来自datagrid的表头的列名及显示名称 处理方法: //获取冻结的数据源并返回key,value格式数据 var GetFroz ...

  4. LC 968. Binary Tree Cameras

    Given a binary tree, we install cameras on the nodes of the tree. Each camera at a node can monitor  ...

  5. 微信小程序开发——使用第三方插件生成二维码

    需求场景: 小程序中指定页面需要根据列表数据生成多张二维码. 实现方案: 鉴于需要生成多张二维码,可以将生成二维码的功能封装到组件中,直接在页面列表循环中调用就好了.也可以给组件添加slot,在页面调 ...

  6. 系统重装之认识UEFI

    UEFI是一种新型的引导方式?他与传统的BIOS引导不同,传统BIOS引导需要经过(开机→BIOS初始化→BIOS自检→引导系统→进入系统)五个步骤来完成引导操作,UEFI只需要(开机→UEFI初始化 ...

  7. Mac删除自带的abc输入法

    1. 安装软件:https://pan.baidu.com/s/15oIzTDojpignoR5MiZ-Q1A 安装并注册 2. 进入到目录,并打开: 1. /Users/toov5/Library/ ...

  8. layui自定义模块

    想把用了layui的页面的一些函数抽取公用,直接引入外部js不可行,只能用layui的模块功能.官网没有说明,但模块名必须和文件名一致 新建yananmod.js文件,内容如下: layui.defi ...

  9. [ Docker ] 基础安装使用及架构

    目录- Centos7 安装 Docker- Docker 架构 1. CentOS7 安装 Docker 目前 docker 有三个分支,moby.docker-ce.docker-ee moby ...

  10. eclipse :代码自动补全不生效解决办法

    参考文章:https://blog.csdn.net/qq_35033270/article/details/79285821 请见下图! 恢复缺省值即可!