安卓使用RecyclerView+HorizontalScrollView 實(shí)現(xiàn)Item整體橫向滑動,上下左右滑動

這個案例是利用豎向的RecyclerView和橫向的HorizontalScrollView 實(shí)現(xiàn)的一個可橫向和豎向滑動的view,

代碼可參考github

如果這個demo的思路幫到了你,請不要吝嗇你的Star 謝謝!

在模擬器上錄了一個效果圖,股票APP中常用的效果,下面來分析一下怎么去做這個

image

gif效果

整體布局如下

image

布局

其實(shí)看似很簡單,也有很多種解決辦法,但是我經(jīng)過試驗(yàn)之后發(fā)現(xiàn)這種是性能最好的,因?yàn)樽钔鈱邮莻€RecyclerView,無任何嵌套,ViewHolder可重復(fù)回收利用,界面絲滑,就是需要處理好手勢以及細(xì)節(jié)問題

這里面幾個比較難的部分,總結(jié)一下,3個難點(diǎn)問題

1.頭布局的HorizontalScrollView如何與下面RecyclerView的Item中HorizontalScrollView實(shí)現(xiàn)同步橫向滾動

2.當(dāng)觸摸下面RecyclerView的單個Item的HorizontalScrollView時,整個右面布局跟隨左右滑動

3.當(dāng)RecyclerView的右邊部分Item滑動到最左邊的時候,下拉刷新,部分item位置會錯位

帶著上面三個問題,逐個來解決

1.HorizontalScrollView的滑動監(jiān)聽,我們可以去看一下,它有一個onScrollChanged方法的回調(diào),

@Override
protected void onScrollChanged(int l,int t,int oldl,int oldt){
    super.onScrollChanged(l,t,oldl,oldt);
}

首先處理觸摸頭部時來滾動下面部分的監(jiān)聽,對頭部的HorizontalScrollView進(jìn)行監(jiān)聽,在這個回調(diào)的方法里面想辦法去滾動item中的每一個HorizontalScrollView就可以了

2.第二個問題,就有點(diǎn)小復(fù)雜;由于下部分是個RecyclerView,就涉及到ViewHolder的緩存復(fù)用機(jī)制,RV的緩存筆記

我的做法是,將每一個ViewHolder保存下來,并在觸摸單個Item的HorizontalScrollView時,在其響應(yīng)的onScrollChanged方法中,滑動除觸摸之外的所有ViewHolder中的HorizontalScrollView

RecyclerView的ViewHolder中緩存ViewHolder

if(!mViewHolderList.contains(holder)){
    mViewHolderList.add(holder);
}

監(jiān)聽當(dāng)前觸摸的item的viewholder中的HorizontalScrollView滾動,并遍歷所有緩存的viewholder,同步滾動其他item的HorizontalScrollView

holder.horItemScrollview.setOnCustomScrollChangeListener((listener,scrollX,scrollY,oldScrollX,oldScrollY)->{
    for(inti=0;i<mViewHolderList.size();i++){
        ItemViewHolder touchViewHolder=mViewHolderList.get(i);
         if(touchViewHolder!=holder){
                touchViewHolder.horItemScrollview.scrollTo(scrollX,0);
        }
    }
    if(null!=onContentScrollListener)onContentScrollListener.onScroll(scrollX);**
    offestX=scrollX;//記錄滾動的距離(增量)**
});

回到第一個問題,這時候就很好解決了,同樣的,遍歷viewholder集合,同步移動頭部HorizontalScrollView的移動距離

這里還有一個問題需要解決,當(dāng)RV可見部分被橫向滾動之后,再上下滾動外層的RV,新創(chuàng)建的ViewHolder需要做一個同步的左右滾動

監(jiān)聽外層RecyclerView的上下滾動,同步滾動內(nèi)部Item的橫向距離(在Item有橫向滾動的時候)

//滑動監(jiān)聽,同步滾動所有item
refreshRv.setOnSlideListener(newRefreshRecyclerView.OnSlideListener(){
    @Override
    publicvoidonSlide(){

    }

    @Override
    publicvoidslideStop(){

    }

    @Override
    publicvoidonScrolled(RecyclerViewrecyclerView,intdx,intdy){
        List<StockSelectionResultAdapter.ItemViewHolder>viewHolderList=mStockSelectionResultAdapter.getViewHolderList();
        if(null!=viewHolderList){
            intsize=viewHolderList.size();
            for(inti=0;i<size;i++){
                viewHolderList.get(i).horItemScrollview.scrollTo(mStockSelectionResultAdapter.getOffestX(),0);
            }
        }
    }
});

3.這個問題的最終原因,還是因?yàn)閂iewHolder的緩存導(dǎo)致,當(dāng)RV被下拉刷新之后,重置數(shù)據(jù),調(diào)用了notifyDataSetChanged,結(jié)合ViewHolder緩存,對數(shù)據(jù)進(jìn)行重新布局,但是當(dāng)我在viewholder的creat方法中無論怎么更改當(dāng)前holder持有的HorizontalScrollView的距離都不生效,還是錯位,而且會出現(xiàn)5個錯位,其他正常,我看了一下正好是那5個緩存的viewholder的HorizontalScrollView滾動距離設(shè)置之后沒有生效,我猜想可能是viewholder取出之后,還沒有進(jìn)行布局之前我設(shè)置了HorizontalScrollView的滾動距離,所以沒有生效,那么怎么監(jiān)聽viewholder的布局呢?

我找了一圈,只找到getViewTreeObserver().addOnGlobalLayoutListener這個,監(jiān)聽view的layout的listener,不知道還有沒有其他方法來監(jiān)聽這個viewholder從緩存中拿出來之后,在什么時機(jī)被layout完成

下面這段代碼在viewholder的creat方法中調(diào)用,即可解決下拉刷新之后錯位問題(這里我用了個flag記錄每個holder是否加載完,加載完之后在這里回調(diào),并設(shè)置flag為true,這樣可以避免這個listener被調(diào)用多次,算得上是個小技巧)

holder.horItemScrollview.getViewTreeObserver().addOnGlobalLayoutListener(()->{
    if(!holder.isLayoutFinish()){
        holder.horItemScrollview.scrollTo(offestX,0);
        holder.setLayoutFinish(true);
    }
});

作者:奮斗小青年Jerome

鏈接:http://www.reibang.com/p/75bba86dd61c

來源:簡書

著作權(quán)歸作者所有邑雅。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處妈经。

安卓使用RecyclerView+HorizontalScrollView 實(shí)現(xiàn)Item整體橫向滑動 - 簡書

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淮野,一起剝皮案震驚了整個濱河市捧书,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骤星,老刑警劉巖经瓷,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異洞难,居然都是意外死亡舆吮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門队贱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來色冀,“玉大人,你說我怎么就攤上這事柱嫌》嫣瘢” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵编丘,是天一觀的道長与学。 經(jīng)常有香客問我,道長嘉抓,這世上最難降的妖魔是什么索守? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮抑片,結(jié)果婚禮上卵佛,老公的妹妹穿的比我還像新娘。我一直安慰自己蓝丙,他們只是感情好级遭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著渺尘,像睡著了一般挫鸽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸥跟,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天丢郊,我揣著相機(jī)與錄音,去河邊找鬼医咨。 笑死枫匾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拟淮。 我是一名探鬼主播干茉,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼很泊!你這毒婦竟也來了角虫?” 一聲冷哼從身側(cè)響起沾谓,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎戳鹅,沒想到半個月后均驶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枫虏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年妇穴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隶债。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡腾它,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出死讹,到底是詐尸還是另有隱情携狭,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布回俐,位于F島的核電站,受9級特大地震影響稀并,放射性物質(zhì)發(fā)生泄漏仅颇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一碘举、第九天 我趴在偏房一處隱蔽的房頂上張望忘瓦。 院中可真熱鬧,春花似錦引颈、人聲如沸耕皮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌停。三九已至,卻和暖如春售滤,著一層夾襖步出監(jiān)牢的瞬間罚拟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工完箩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赐俗,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓弊知,卻偏偏與公主長得像阻逮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秩彤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345