1. 程式人生 > >react-native-viewpager踩坑記

react-native-viewpager踩坑記

react-native-viewpager是一個輪播圖元件,最近有一個需求是有一個測試題頁面,我第一反應是用一個輪播圖元件,只是把輪播圖替換成輪播檢視,每個視圖裡面內容比圖片複雜一些而已。。。然而,我只是這麼想想,實際做起來還不知道會遇到什麼坑,開始踩坑吧。

這裡寫圖片描述

npm install react-native-viewpager --save

一開始就遇到一個比較坑的問題,我直接谷歌搜尋react-native-viewpager 出來的第一個一看是github上面的,點進去也叫這個名字,沒毛病啊,跟著教程安裝,輸入安裝命令:npm install rn-viewpager --save

,然後我挺納悶,為啥安裝名字變了,回到谷歌搜尋往下翻了幾個,好像都是這個元件,比較尷尬的是我安裝一直失敗,導致我照著教程寫程式碼一直報錯,無奈我直接在github 上搜索,結果出現在第一個的居然不是我之前搜出來的這個,搞了半天我連元件都安裝錯了,react-native-viewpager 這是正確的github地址。

接著看教程,太簡短了。。簡短到我懷疑人生,

var ViewPager = require('react-native-viewpager');
<ViewPager
    dataSource={this.state.dataSource}
    renderPage={this
._renderPage}/>

現在這個時代誰還用es5,先把引入方式改一下:
import ViewPager from 'react-native-viewpager';
接著看,看這個結構是不是跟ListView元件一樣一樣的?先暫時不管配置引數,我的第一目標是先讓檢視輪播起來,這裡也沒寫dataSource應該怎麼定義,renderPage應該怎麼渲染,我理所當然的認為跟listview是一樣的,於是我的程式碼是這樣寫的:

    const ds = new ListView.DataSource({
      rowHasChanged: (r1,r2) => r1
!== r2 }); this.state = { dataSource : ds.cloneWithRows(data), }
<ViewPager 
        dataSource = {this.state.dataSource}
        renderPage = {this._renderPage.bind(this)} />
_renderPage(rowData,sectionID,rowID) {
}

然後報錯了:
這裡寫圖片描述
哈哈哈,我就知道沒這麼簡單,應該是dataSource出了問題,於是我又去找,總算找到這個是怎麼用的了:

const ds = new ViewPager.DataSource({
      pageHasChanged: (p1,p2) => p1 !== p1,
   });
    this.state = {
      dataSource: viewPagerDs.cloneWithPages(data),
    }

再模擬幾條假的資料,就能看到輪播圖效果了。
當然,我的任務遠不止這些,考慮到我的實際專案需求,首先不能根據手勢切換上一條下一條資料,只能點選上一題和下一題切換,所以我要先禁用手勢切換。自動播放也不行,看一下配置引數:

dataSource: this is require to provide pages data,
renderPage: this is require to render page view,
autoPlay: true to turn page automatically,
initialPage: to set the index of the first page to load,
isLoop: true to run in infinite scroll mode,
locked: true to disable touch scroll,
onChangePage: page change callback,
renderPageIndicator: render custom ViewPager indicator. (是否顯示小圓點)
initialPage: show initially some other page than first page.

找到我需要的兩個引數是autoPlay和locked,autoPlay是是否自動播放,設定為false,locked是是否鎖定手勢滾動,設定為true.
這一步很簡單,然後可以看到預設的翻頁小圓點樣式是在圖片下方的,而我希望小圓點在最上方,而且是紅色,而且還有顏色透明度的變化和當前選中頁的圓點大小比其他圓點大的效果,然後看一下引數,renderPageIndicator 值為true顯示小圓點,但是我需要修改小圓點的樣式,這裡沒有暴露出可以修改小圓點樣式的屬性,沒辦法,去找原始碼吧,把原始碼蒐羅出來改改。順便提一下,所有安裝的元件都在node_modules中,在這個資料夾中修改檔案除非重新react-native run-android 才會生效,所以可以把這個元件移動到跟pages,container等資料夾同級的libs資料夾下。
順著renderPageIndicator在ViewPage.js檔案中找到關鍵程式碼:

renderPageIndicator(props) {
    if (this.props.renderPageIndicator === false) {
      return null;
    } else if (this.props.renderPageIndicator) {
      return React.cloneElement(this.props.renderPageIndicator(), props);
    } else {
      return (
        <View style={styles.indicators}>
          <DefaultViewPageIndicator {...props} />
        </View>
      );
    }
  },

可以看到這裡的這個view裝小圓點的外層檢視了,看一下外層檢視的樣式:

 indicators: {
    flex: 1,
    alignItems: 'center',
    position: 'absolute',
    bottom: 10,
    left: 0,
    right: 0,
    backgroundColor: 'transparent',
  },

再繼續找小圓點的樣式,在DefalutViewPageIndicator.js中:

dot: {
    width: DOT_SIZE,
    height: DOT_SIZE,
    borderRadius: DOT_SIZE / 2,
    backgroundColor: '#E0E1E2',
    marginLeft: DOT_SAPCE,
    marginRight: DOT_SAPCE,
  },

  curDot: {
    position: 'absolute',
    width: DOT_SIZE,
    height: DOT_SIZE,
    borderRadius: DOT_SIZE / 2,
    backgroundColor: '#80ACD0',
    margin: DOT_SAPCE,
    bottom: 0,
  },

很明顯,dot就是未選中小圓點的樣式,curDot就是選中小圓點的樣式,然後等等!!不要急著改,萬一下一個地方也用了這個元件但是樣式跟現在的樣式需求不一樣呢?最好的辦法就是從父元件傳遞樣式屬性到DefalutViewPageIndicator.js檔案,(因為要修改的樣式有點多,所以我直接就把整個style傳遞給子元件了),先弄清楚元件結構:DefalutViewPageIndicator.js是ViewPage.js的子元件,ViewPage.js是我的頁面的子元件,要從我的頁面傳遞樣式給孫子元件:
我的頁面:

<ViewPager 
        dataSource = {this.state.questionDataSource}
        renderPage = {this._renderPage.bind(this)} 
        autoPlay = {false}
        locked = {true}
        dotViewStyle={{}}
        dotStyle = {{}}
        selectedDotStyle = {{}}/>

dotStyle和selectedDotStyle就是我自定義用來控制小圓點樣式的屬性,dotViewStyle是小圓點外層檢視樣式
在ViewPage.js中:

{this.renderPageIndicator({goToPage: this.goToPage,
                            pageCount: pageIDs.length,
                            activePage: this.state.currentPage,
                            scrollValue: this.state.scrollValue,
                            scrollOffset: this.childIndex,
                            dotViewStyle: PropTypes.object,//增加
                            dotStyle: this.props.dotStyle,//增加
                            selectedDotStyle: this.props.selectedDotStyle//增加
                          })}
propTypes: {
    //...
    animation: PropTypes.func,
    initialPage: PropTypes.number,
    //add by melody
    dotStyle: PropTypes.object,//增加
    selectedDotStyle: PropTypes.object,//增加
  },
<View style={[styles.indicators,this.props.dotViewStyle]}>
     <DefaultViewPageIndicator {...props} />
</View>

從父元件拿到這兩個屬性繼續傳遞給DefalutViewPageIndicator.js:
在DefalutViewPageIndicator.js中:

propTypes: {
    goToPage: React.PropTypes.func,
    activePage: React.PropTypes.number,
    pageCount: React.PropTypes.number,
     //add by melody
    dotStyle: React.PropTypes.object,//增加
    selectedDotStyle: React.PropTypes.object,//增加
  },

<View style={styles.dot} />
改為:
<View style={[styles.dot,this.props.dotStyle]} />

<Animated.View style={[styles.curDot, {left}]} />
改為:
<Animated.View style={[styles.curDot, this.props.selectedDotStyle, {left}]} />

再去修改樣式已經能起作用了,但是我需要的樣式改起來沒我想象中的簡單,不過我慢慢調吧,除了樣式,還有最重要的是給上一題和下一題繫結事件。

相關推薦

react-native-viewpager

react-native-viewpager是一個輪播圖元件,最近有一個需求是有一個測試題頁面,我第一反應是用一個輪播圖元件,只是把輪播圖替換成輪播檢視,每個視圖裡面內容比圖片複雜一些而已。。。然而,我只是這麼想想,實際做起來還不知道會遇到什麼坑,開始踩坑

Android 真機搭建 React-Native 環境記錄

本文記錄了我搭建 React-Native 專案時踩過的坑(下稱 RN),以及使用 Android 真機執行 RN 專案遇到的問題,供大家參考。 初始化 RN 專案 執行 react-native init [your project name] 命令在本地初始化一個 RN 專案

react-native開發之 ios上react-native-vector-icons 的error:unRecognized font family 'FontAwesome'

RN開發過程中使用了第三方圖示庫,由於對iOS也不是特別熟,所以搞了兩天才跨過去,解決完畢後分享一下,畢竟RN開發資源還是比較稀缺的,多一點貢獻是一點。 解決問題首先第一步那絕對是官網找,react-native-vector-icons github連結地址

react native新手-遇到warning的相關解決辦法

出現Warning:Failed child context type: Invalid child context 'virtualizedCell.cellKey' of type 'number' supplied to 'CellRenderer',expected

react native

react native 碰到的幾個坑。記錄如下。 1.com.facebook.react.common.JavascriptException: undefined is not an object (evaluating 'n.internals.offset[e]'), stack:

React-Native android在windows下的

坑很多,跳之前做好準備。沒有VPN的同學請瀏覽完本文後慎行。 你需要先安裝最新版本的node.js(我最後使用的是v4.1.2),前往官網下載>> 注:我win7已經安裝過Visual Studio 2013和Android開發環境(也踩了不少坑,後面有

react native(建立指定的React-Native版本)

建立指定的React-Native版本 剛剛開始學習React Native,很多都不懂,搭建環境的時候遇到了挺多問題的,一直在折騰。 我是按照React Native文件來搭建環境的,安裝react-native-cli使用的是下面的命令。 npm in

React Native

一、遇到過的坑 1.1 執行Downloading https://services.gradle.org/distributions/gradle-2.4-all.zip時報錯 解決方法:複製報錯的下載連結,用迅雷下載, 將專案地址中的AwesomeP

Android原生專案整合React Native

最近在學習React Native,將Android原生專案整合React Native實現混合開發。參考官網和其他一些相關資料,自己動手一步一步操作,發現真的是一步步踩坑再填坑的過程,此文章記錄整合React Native的步驟和出現的問題,方便以後查閱。

react native

react native 碰到的幾個坑。記錄如下。 1.com.facebook.react.common.JavascriptException: undefined is not an object (evaluating 'n.internals.offset[e]'

create-react-app

tcs onf class working zip als mpi iconfont hat 前言 哇,不的不說這個react 這個腳手架create-react-app腳確實有很多問題,哈哈,下面來看看吧有哪些坑: 引用sass或者less 記得16

react native 的 很多很多!自己已

1. 從後臺傳回來的日期格式可能是這樣(2018-05-04 13:20:09),“-”這個可能轉換時這個時間就會變空。所以我們要這樣做:new Date(data.curriculaTime.replace(/-/g, "/"));—————————————————————

React三】React項目報錯Can't perform a React state update on an unmounted component

-o clas sha ces ESS eventbus event log back 意思為:我們不能在組件銷毀後設置state,防止出現內存泄漏的情況 分析出現問題的原因: 我這裏在組件加載完成的鉤子函數裏調用了一個EventBus的異步方法,如果監聽到異步方法,則

React一】React項目中禁用瀏覽器雙擊選中文字的功能

一個 art 文字 star reac return 禁用 tar htm 常規項目,我們只需要給標簽加一個onselectstart事件,return false就可以 例: <div onselectstart="return false;"

React四】React專案中引入並使用js-xlsx上傳外掛(結合antdesign的上傳元件)

最近有一個前端上傳並解析excel/csv表格資料的需求。 於是在github上找到一個14K star的前端解析外掛 github傳送門 官方也有,奈何實在太過於淺薄。於是做了以下整理,避免道友們少走一些彎路。 安裝依賴 yarn add xlsx //或 npm install xlsx 專案中引入

HookReact Hook react-unity-webgl

  自公司前後分離上手React以來,一個坑一個坑的踩,Class的全生命週期雲裡霧裡,還麼屢明白,就抱上了Hook的大腿不鬆手,確實爽到飛起。修改到Hook的過程基本比較順暢,直接少了三分之一的程式碼,元件更容易封裝,除錯更方便,諸多優點在此不再贅述,已有各路大佬紛紛評價,此處貼上中文官方地址:React-

Visual Studio For MacOS (二)

mirrors class app macosx andro mce 資料 library devel Visual Studio For MacOS安裝安卓SDK。 系統默認安裝了安卓6.0 API23的SDK。 但是我需要安卓7.0的,API24. 遂安裝。

spark共享變量

park oid and 共享變量 roi syn out his andro %E5%9C%A8android%E4%B8%AD%E6%80%8E%E4%B9%88%E7%94%A8this removeviewinlayout?к????? repo????л???

Linux使用

gre 16px -- 機器 操作 onf 問題: 失敗 gbk Ubuntu安裝坑: 1、對於新手第一次安裝ubuntu,特殊情況會出現因為分辨率問題導致安裝界面不全,無法進行下一步操作。 解決方案:使用alt+鼠標左鍵拖動屏幕Linux文件名亂碼問題:

java-getResourceAsStream

mov load color () tar type 當前 blog ase 本文主要是研究下面集中方法到底誰才能真正的load到文件,你能一眼看出來嗎? GetResourcesSample.class.getClassLoader.getResourceAsStream