React Native 开发豆瓣评分(八)首页开发

Stella981
• 阅读 353

首页完成效果展示:

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;
    ...
}

至此,首页算是开发完了。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Eclipse插件开发_学习_00_资源帖
一、官方资料 1.eclipseapi(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fhelp.eclipse.org%2Fmars%2Findex.jsp%3Ftopic%3D%252Forg.eclipse.platform.doc.isv%252Fguide%2
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这