React Native 開發豆瓣評分(八)首頁開發

来源:https://www.cnblogs.com/hl1223/archive/2019/07/19/11214488.html
-Advertisement-
Play Games

首頁完成效果展示: 一、開發占點陣圖組件 在沒有數據的時候使用占點陣圖替代 items 的位置。 在 components 目錄里創建 moviesItemPlaceholder.js 二、首頁數據請求 使用 postman 之類的工具可以看到,首頁介面返回的數據欄位大致一樣,數據均在 subject_ ...


首頁完成效果展示:

一、開發占點陣圖組件

在沒有數據的時候使用占點陣圖替代 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;
    ...
}

至此,首頁算是開發完了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.tar -jxvf geos-3.6.0.tar.bz2cd geos-3.6.0/./configure --prefix=/opt/geos360makemake install 2. tar -zxvf proj-4.9.3.tar.gzcd proj-4.9.3/./configure ...
  • ./orzdba -lazy -rt -S /u01/svr/working/my3306/run/mysql.sock mysql -s --skip-column-names -h127.0.0.1 -urep -P3306 -prep123 -Dmysql -S /u01/svr/workin ...
  • 今天做一個APP裡面設置頁面(個人中心) 就是一個列表菜單 頂部是一個頭像和賬戶標題, 底部為一個退出登錄按鈕 當然我第一時間就想到了UITableView, HeaderView, FooterView 期初我是這樣寫的, 但是運行就報錯了 我第一時間想到了, 是UITableView沒進行刷新布 ...
  • 微信小程式實現點擊拍照長按錄像功能 代碼裡面註釋寫的都很詳細,直接上代碼。官方的組件屬性中有觸摸開始和觸摸結束屬性。本功能依靠這些屬性實現。 .wxml代碼: .wxss代碼: .js代碼: // pages/camera/camera.js Page({ / 頁面的初始數據 / data: { c ...
  • 註:該思維學習自另一個博客:https://blog.csdn.net/software0017/article/details/80317348 以下為我自己總結的jQuery結構: ...
  • 利用dataTable展示數據列表時,當選擇每頁顯示數量時,滾動條還是按照頁面初始化時顯示的,導致無法滾動查看下麵的數據, 在stackoverflower 找到一個可用的方法,但不知道為什麼僅寫 $('#myDiv').getNiceScroll().resize()無效??? ...
  • 這幾天在項目中遇到了要使用樹形選擇框, 而且要求比較複雜,具體敘述如下: 首先是有個選擇框,左邊選擇是適用的商品,右邊顯示已經選擇的商品.也就是說,左邊每次勾選操作,都要觸發一個事件去刷新右邊的頁面, 而且,左邊商品如果選擇大類,則右邊顯示大類,其下小類都不顯示 也就是說有父子聯動的關係. 剛開始的 ...
  • vue組件之間的通信有很多種方式,最常用到的就是父子組件之間的傳值,但是當項目工程比較大的時候,就會出現兄弟組件之間的傳值,跨級組件之間的傳值。不可否認,這些都可以類似父子組件一級一級的轉換傳遞,但是當項目比較大,功能比較複雜的時候,就會變得比較冗餘,代碼不利於維護;這時候可能會有很多人使用到vue ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...