React Native整體滑動(dòng)的標(biāo)簽頁(yè)(標(biāo)簽頁(yè)嵌套口叙,微博熱搜頁(yè))

由于疫情影響炼绘,春節(jié)在家足足呆了快二十天了,葛優(yōu)躺了幾天后覺(jué)得還是得做點(diǎn)什么妄田,于是想著把之前寫(xiě)的東西再總結(jié)下和學(xué)點(diǎn)新東西俺亮。
年前一段時(shí)間,RN項(xiàng)目需要用一個(gè)整體可以縱向滑動(dòng)的標(biāo)簽頁(yè)疟呐。網(wǎng)上沒(méi)有找到讓人滿意的組件脚曾,于是打算自己封裝一個(gè),期間遇到了一些問(wèn)題启具,后面算是能達(dá)到比較好的效果本讥,并且兼容ios、android平臺(tái)了富纸,決定趁著這段空閑時(shí)間分享出來(lái)和大家一起探討囤踩,共同進(jìn)步。
大家可以直接點(diǎn)擊跳轉(zhuǎn)源碼晓褪。
組件名:react-native-head-tab-view

iOS效果圖


demo_ios.gif

Android效果圖:

demo_android.gif

開(kāi)發(fā)思路:
由于是整體滑動(dòng)的標(biāo)簽頁(yè)堵漱,那首先得有一個(gè)標(biāo)簽頁(yè)組件,我之前正好封裝了一個(gè)涣仿,于是這個(gè)組件就在其基礎(chǔ)上進(jìn)行開(kāi)發(fā)了勤庐,下面是我當(dāng)時(shí)的一些思路。
我在設(shè)計(jì)之初好港,最先想到是用ScrollView包裹標(biāo)簽頁(yè)愉镰,達(dá)到整體滑動(dòng)的效果,但是會(huì)有諸多問(wèn)題钧汹,列舉一二丈探,比如幾個(gè)標(biāo)簽頁(yè)高度不同,ScrollView必須能容納最長(zhǎng)的那個(gè)標(biāo)簽頁(yè)拔莱,那從最長(zhǎng)的標(biāo)簽頁(yè)滑動(dòng)到比較短的標(biāo)簽頁(yè)時(shí)就會(huì)有白條碗降,需要另外處理隘竭,比較消耗RN的性能;再就是頂部滑出屏幕和滑入屏幕時(shí)讼渊,需要在ScrollView和標(biāo)簽頁(yè)直接切換手勢(shì)动看,非常影響流暢性。
后面決定用動(dòng)畫(huà)去做這件事爪幻,轉(zhuǎn)換思路后豁然開(kāi)朗菱皆,至少性能可以達(dá)到原生級(jí)別。
接下來(lái)拆解需求挨稿,無(wú)非是要達(dá)到以下幾個(gè)目的:

  • 標(biāo)簽頁(yè)左右滑動(dòng)功能正常仇轻,頂部加了一個(gè)頭部Head組件。
  • 任何一個(gè)標(biāo)簽頁(yè)滑動(dòng)時(shí)叶组,計(jì)算距離頂部的距離拯田,決定Head組件的動(dòng)畫(huà)行為历造。
  • 共享不同標(biāo)簽頁(yè)的垂直滑動(dòng)距離甩十,達(dá)到共同操控Head組件的目的
  • 兼容標(biāo)簽頁(yè)下官方的所有滑動(dòng)組件(ScrollView,F(xiàn)latList吭产,SectionList)

那只需要針對(duì)以上問(wèn)題一一解決就可以了侣监。

  • 首先問(wèn)題一,需要加Head組件臣淤,那怎么加橄霉,加到哪里,可以看下面(左)邑蒋,標(biāo)簽頁(yè)組件正常布局姓蜂,只讓所有標(biāo)簽頁(yè)子頁(yè)面加了個(gè)paddingTop,空出一個(gè)Head組件的位置医吊。
    third.png
  • 問(wèn)題二比較簡(jiǎn)單钱慢,計(jì)算滑動(dòng)距離小于Head高度時(shí),通過(guò)區(qū)間動(dòng)畫(huà)決定Head的軌跡卿堂。
  • 解決問(wèn)題三只需要將記錄Y軸位置的對(duì)象提升到更高一級(jí)束莫,放在標(biāo)簽頁(yè)組件中,然后下發(fā)到各個(gè)標(biāo)簽頁(yè)子頁(yè)面草描,由當(dāng)前正在滾動(dòng)的子頁(yè)面去記錄和維護(hù)這個(gè)對(duì)象览绿。
  • 問(wèn)題四的解決辦法只需要封裝一個(gè)高階組件:接受當(dāng)前使用的滑動(dòng)組件,返回一個(gè)滿足以上功能的新組件穗慕,也能同時(shí)達(dá)到封裝內(nèi)聚的目的饿敲。

補(bǔ)充幾個(gè)點(diǎn):

  1. 由于Tabbar初始位置在屏幕頂部,需要給它一個(gè)和滾動(dòng)距離成反比的動(dòng)畫(huà)逛绵,也就是說(shuō)初始位移值是Head的高度怀各,到最后位移值是0栗竖,也就是回到原位置頂在頂部。(如下圖)


    move.png

    滾動(dòng)距離超出Head高度后:


    end.png
  2. 為了達(dá)到效果渠啤,我們?cè)跐L動(dòng)標(biāo)簽Tab1頁(yè)面時(shí)狐肢,是需要Tab2、Tab3也同時(shí)滾動(dòng)的沥曹,那就會(huì)出現(xiàn)如果Tab2份名、Tab3未加載出數(shù)據(jù),或者加載的數(shù)據(jù)少妓美,不夠滾動(dòng)的情況僵腺。我采取的是通過(guò)動(dòng)態(tài)計(jì)算,用占位高度去彌補(bǔ)的方式壶栋。

  3. 由于標(biāo)簽頁(yè)子頁(yè)面是用高階組件HPageViewHoc包裹辰如,我用了Ref轉(zhuǎn)發(fā),能通過(guò)ref直接取到被包裹住的那個(gè)組件贵试,但是內(nèi)部用了const AnimatePageView = Animated.createAnimatedComponent(WrappedComponent)琉兜,你取到的ref會(huì)是一個(gè)動(dòng)畫(huà)對(duì)象,請(qǐng)?jiān)偻ㄟ^(guò)getNode()獲取實(shí)際的FlatList組件毙玻,如下面代碼豌蟋。

import { HPageViewHoc } from 'react-native-viscous-tabview'
const HFlatList = HPageViewHoc(FlatList)

render() {
        const { data } = this.state;
        return (
            <HFlatList
                {...this.props}
                ref={_ref=>this.list=_ref}
                data={data}
                renderItem={this.renderItem.bind(this)}
                keyExtractor={(item, index) => index.toString()}
            />
        )
    }
handleRef(){
    this.list.getNode()...
}

如果大家有什么疑問(wèn)可以在文章下方評(píng)論區(qū)留言,如果有bug請(qǐng)?zhí)嵩?a target="_blank">issues區(qū)
桑滩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梧疲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子运准,更是在濱河造成了極大的恐慌幌氮,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胁澳,死亡現(xiàn)場(chǎng)離奇詭異该互,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)听哭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)慢洋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人陆盘,你說(shuō)我怎么就攤上這事普筹。” “怎么了隘马?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵太防,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蜒车,這世上最難降的妖魔是什么讳嘱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮酿愧,結(jié)果婚禮上沥潭,老公的妹妹穿的比我還像新娘。我一直安慰自己嬉挡,他們只是感情好钝鸽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著庞钢,像睡著了一般拔恰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上基括,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天颜懊,我揣著相機(jī)與錄音,去河邊找鬼风皿。 笑死河爹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的揪阶。 我是一名探鬼主播昌抠,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鲁僚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起裁厅,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冰沙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后执虹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拓挥,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年袋励,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侥啤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茬故,死狀恐怖盖灸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情磺芭,我是刑警寧澤赁炎,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布,位于F島的核電站钾腺,受9級(jí)特大地震影響徙垫,放射性物質(zhì)發(fā)生泄漏讥裤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一姻报、第九天 我趴在偏房一處隱蔽的房頂上張望己英。 院中可真熱鬧,春花似錦吴旋、人聲如沸剧辐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荧关。三九已至,卻和暖如春褂傀,著一層夾襖步出監(jiān)牢的瞬間忍啤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工仙辟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留同波,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓叠国,卻偏偏與公主長(zhǎng)得像未檩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子粟焊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容