成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android輕松實(shí)現(xiàn)RecyclerView懸浮條

移動(dòng)開(kāi)發(fā) Android
在我們?cè)谒nstagram的動(dòng)態(tài)時(shí),你是否注意到這樣一個(gè)小小的動(dòng)效,就是當(dāng)一條動(dòng)態(tài)(以卡片形式呈現(xiàn))向上滑動(dòng)時(shí),動(dòng)態(tài)卡片的頭部會(huì)始終懸浮在列表最上方,直到下一張動(dòng)態(tài)卡片的頭部將它頂?shù)舨⑻鎿Q它懸浮著。

在我們?cè)谒nstagram的動(dòng)態(tài)時(shí),你是否注意到這樣一個(gè)小小的動(dòng)效,就是當(dāng)一條動(dòng)態(tài)(以卡片形式呈現(xiàn))向上滑動(dòng)時(shí),動(dòng)態(tài)卡片的頭部會(huì)始終懸浮在列表最上方,直到下一張動(dòng)態(tài)卡片的頭部將它頂?shù)舨⑻鎿Q它懸浮著。言語(yǔ)可能說(shuō)不清楚,就直接來(lái)看一下它的效果好了。 

 

 

 

綜合我上面的文字描述加上這張Gif圖,我想大家應(yīng)該知道這是個(gè)什么樣的效果了吧。那么不廢話了,接下來(lái)我就來(lái)說(shuō)說(shuō)一種很簡(jiǎn)單的實(shí)現(xiàn)方法吧。

思路

雖然實(shí)現(xiàn)起來(lái)炒雞簡(jiǎn)單,但還是花了我一個(gè)多小時(shí)的時(shí)間思考實(shí)現(xiàn)。先說(shuō)說(shuō)思考過(guò)程吧,那天中午,Instagram給我推了一條消息(哈,就是我最喜歡的偶像金泰妍更新了Ins),于是我就點(diǎn)進(jìn)去看了,喜歡了之后就開(kāi)始研究這個(gè)效果,我反復(fù)地上下滑這個(gè)列表,因?yàn)镮ns的列表有滾動(dòng)條,我就發(fā)現(xiàn)每次滾動(dòng)條在那個(gè)懸浮條附近的時(shí)候就會(huì)特別短。看到這個(gè)現(xiàn)象,敏銳的你是不是察覺(jué)到了什么?沒(méi)錯(cuò),我感覺(jué)這個(gè)就像是FrameLayout的效果,一個(gè)FrameLayout里按順序有列表,懸浮條兩個(gè)View,懸浮條覆蓋在列表的上方,它在合適的時(shí)機(jī)更新自己的位置,在合適的時(shí)機(jī)更新自己的信息,然后看上去就像是一個(gè)懸浮的效果。

接下來(lái)我們思考的核心就轉(zhuǎn)移到了如何確定并找到這個(gè)合適的時(shí)機(jī)。

再仔細(xì)觀察上面的Gif圖,我們可以確定當(dāng)?shù)诙€(gè)列表項(xiàng)的頭部距離列表頂端一個(gè)懸浮條的距離時(shí),懸浮條隨著列表的滑動(dòng)改變自身的位置,從而看起來(lái)像是被頂?shù)舻男Ч?。?huà)一張簡(jiǎn)單位置示意圖 

 

 

 

那么,數(shù)據(jù)更新的時(shí)機(jī)也很容易確定,就是在懸浮條恰好完全被頂?shù)舻臅r(shí)候,更新自己的數(shù)據(jù),并移動(dòng)到列表頂部。

至于如何找到這個(gè)時(shí)機(jī)會(huì)在接下來(lái)的實(shí)現(xiàn)部分講解。

實(shí)現(xiàn)

建立布局

如上面所言,就是一個(gè)簡(jiǎn)單的FrameLayout。

  1. <FrameLayout 
  2.     android:layout_width="match_parent" 
  3.     android:layout_height="match_parent" 
  4.     app:layout_behavior="@string/appbar_scrolling_view_behavior"
  5.  
  6.     <android.support.v7.widget.RecyclerView 
  7.         android:id="@+id/feed_list" 
  8.         android:layout_width="match_parent" 
  9.         android:layout_height="match_parent" 
  10.         android:background="@android:color/white" 
  11.         android:scrollbars="vertical" /> 
  12.  
  13.     <your-head-layout> 
  14.     …… 
  15.     </your-head-layout> 
  16. </FrameLayout>  

注意這里FrameLayout的第二個(gè)child應(yīng)該為你列表項(xiàng)要懸浮顯示的布局。

找到時(shí)機(jī)

根據(jù)我們的思路,我們首先要找到第二個(gè)列表項(xiàng)的頭部距離列表頂端一個(gè)懸浮條的距離時(shí)的那個(gè)時(shí)機(jī),如果我們能找到這個(gè)時(shí)機(jī),那么第二個(gè)時(shí)機(jī)也相當(dāng)于找出來(lái)了。

這里我們使用的是RecyclerView來(lái)實(shí)現(xiàn)列表,我們都知道RecyclerView的列表布局是由LayoutManager來(lái)確定的,由于一般要實(shí)現(xiàn)懸浮條顯示效果的列表一般都為線性列表,即我們一般會(huì)使用LinearLayoutManager。通過(guò)LinearLayoutManager,我們可以很方便的獲取到RecyclerView中相應(yīng)位置的View,這里我們需要獲取當(dāng)前懸浮條數(shù)據(jù)來(lái)源的View和其下一個(gè)數(shù)據(jù)來(lái)源的View。這兩個(gè)View有什么用呢?懸浮條顯示的信息是來(lái)自***個(gè)可見(jiàn)View的,而其下方的View正是第二個(gè)列表項(xiàng),我們可以獲取到它的top值。好了接下來(lái)就真的很簡(jiǎn)單了,我們只要給RecyclerView加一個(gè)ScrollListener,并在相應(yīng)的回調(diào)里做之前我們想好的事就ok了,來(lái)看一下代碼

  1. mFeedList.addOnScrollListener(new RecyclerView.OnScrollListener() { 
  2.     @Override 
  3.     public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
  4.         super.onScrollStateChanged(recyclerView, newState); 
  5.         mSuspensionHeight = mSuspensionBar.getHeight(); 
  6.     } 
  7.  
  8.     @Override 
  9.     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
  10.         super.onScrolled(recyclerView, dx, dy); 
  11.         View view = linearLayoutManager.findViewByPosition(mCurrentPosition + 1); 
  12.         if (view != null) { 
  13.             if (view.getTop() <= mSuspensionHeight) { 
  14.                 mSuspensionBar.setY(-(mSuspensionHeight - view.getTop())); 
  15.             } else { 
  16.                 mSuspensionBar.setY(0); 
  17.             } 
  18.         } 
  19.  
  20.         if (mCurrentPosition != linearLayoutManager.findFirstVisibleItemPosition()) { 
  21.             mCurrentPosition = linearLayoutManager.findFirstVisibleItemPosition(); 
  22.             mSuspensionBar.setY(0); 
  23.  
  24.             updateSuspensionBar(); 
  25.         } 
  26.     } 
  27. });  

Tips:其中mCurrentPosition為懸浮條信息來(lái)自的那個(gè)列表項(xiàng)在RecyclerView的位置。還有這里的ScrollListener可以添加多個(gè),在RecyclerView中會(huì)檢查所有的ScrollListener并觸發(fā)。

One more thing...

接下來(lái),我們還需要……開(kāi)玩笑,哪來(lái)的One more thing,我們已經(jīng)完成了?什么?這么快?這么一點(diǎn)代碼?恩,沒(méi)錯(cuò),就是只要這么一點(diǎn)代碼就好了,我們來(lái)看一下***我們實(shí)現(xiàn)的效果(當(dāng)然最終效果的好壞還是取決與你列表項(xiàng)的布局,比如在Ins里這個(gè)效果就很好看呢~) 

 

 

 

補(bǔ)充

上面這種情況我們RecyclerView的Item是單一的,但是我們的列表Item通常有很多種,只有在滑到我們想要類型的Item時(shí)才需要更新我們的懸浮條信息。比如很常見(jiàn)的通訊錄,在我們滑到從A開(kāi)頭聯(lián)系人滑到B開(kāi)頭聯(lián)系人時(shí),懸浮條的信息才從A變?yōu)锽;再比如印象筆記的筆記列表,頂部的懸浮條是根據(jù)筆記的日期改變的。

那么,遇到這種情況我們應(yīng)該怎么簡(jiǎn)單修改代碼來(lái)實(shí)現(xiàn)我們需求呢?

其實(shí)很簡(jiǎn)單,思路已經(jīng)由上面確定了,只是我們要讓?xiě)腋l移動(dòng)的時(shí)機(jī)變化,變得更窄了,同時(shí)我們要更新的數(shù)據(jù)內(nèi)容也發(fā)生了變化(這當(dāng)然需要我們變換相應(yīng)的布局)。

  1. mFeedList.addOnScrollListener(new RecyclerView.OnScrollListener() { 
  2.     @Override 
  3.     public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
  4.         super.onScrollStateChanged(recyclerView, newState); 
  5.         mSuspensionHeight = mSuspensionBar.getHeight(); 
  6.     } 
  7.  
  8.     @Override 
  9.     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
  10.         super.onScrolled(recyclerView, dx, dy); 
  11.         //我們只是簡(jiǎn)單的收窄了我們讓?xiě)腋l移動(dòng)的條件,這里就是ItemType必須對(duì)應(yīng)時(shí)才發(fā)生移動(dòng) 
  12.           if (adapter.getItemViewType(mCurrentPosition + 1) == MultiFeedAdapter.TYPE_TIME) { 
  13.             View view = linearLayoutManager.findViewByPosition(mCurrentPosition + 1); 
  14.             if (view != null) { 
  15.                 if (view.getTop() <= mSuspensionHeight) { 
  16.                     mSuspensionBar.setY(-(mSuspensionHeight - view.getTop())); 
  17.                 } else { 
  18.                     mSuspensionBar.setY(0); 
  19.                 } 
  20.             } 
  21.         } 
  22.  
  23.         if (mCurrentPosition != linearLayoutManager.findFirstVisibleItemPosition()) { 
  24.             mCurrentPosition = linearLayoutManager.findFirstVisibleItemPosition(); 
  25.             mSuspensionBar.setY(0); 
  26.  
  27.             updateSuspensionBar(); 
  28.         } 
  29.     } 
  30. });  

上面的代碼我們只要注意注釋處,其他的和之前給出的相同。

總之,雖然大家的需求可能不同,但萬(wàn)變不離其宗。只要掌握了思路,什么需求都不怕。

Github 上已增加相應(yīng)代碼,***看一下我們的效果,只在時(shí)間變化時(shí)才移動(dòng)懸浮條. 

 

 

 

結(jié)語(yǔ)

哈哈,是不是很簡(jiǎn)單呢,***再說(shuō)一下封裝的事,本來(lái)我是想封裝一下的,由于每個(gè)人的列表布局都不一樣,數(shù)據(jù)更新方式也不一樣,就不封裝了,是的,我水平不行,雖然我不想承認(rèn)~不過(guò)代碼真心特別少哦。希望這篇文章可以對(duì)你有幫助,我也會(huì)繼續(xù)努力的。

責(zé)任編輯:龐桂玉 來(lái)源: 安卓巴士Android開(kāi)發(fā)者門(mén)戶
相關(guān)推薦

2011-05-31 16:38:47

Android 實(shí)現(xiàn)語(yǔ)音

2014-08-18 14:18:07

Android桌面懸浮

2011-03-15 10:08:22

2010-07-16 10:31:02

Batch Telne

2022-07-28 14:20:44

懸浮球鴻蒙

2013-06-03 17:17:14

Android開(kāi)發(fā)Android程序Android手機(jī)平板

2009-12-18 17:29:02

Ruby創(chuàng)建XML

2010-06-02 18:29:36

搭建SVN

2011-08-22 15:09:37

nagios網(wǎng)絡(luò)監(jiān)控

2011-04-14 10:18:20

數(shù)據(jù)遷移

2010-08-05 15:06:19

Flex數(shù)據(jù)綁定

2010-06-03 15:13:34

Hadoop Hdfs

2017-03-13 10:11:28

AndroidRecyclerVie功能介紹

2011-05-06 15:34:02

打印機(jī)word

2017-05-11 15:01:43

Androidweb布局

2013-01-16 15:07:30

Android NDKAndroid開(kāi)發(fā)

2010-08-26 15:59:38

DIV圓角

2010-09-13 16:04:27

CSS控制自動(dòng)換行

2021-07-29 13:06:29

Python機(jī)器學(xué)習(xí)編程語(yǔ)言

2011-04-11 13:53:32

弱電布線
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 97福利在线| 日韩av在线一区二区三区 | 操操操操操 | 福利精品 | 91亚洲精品久久久电影 | 亚洲天堂av网 | 国产一级片网站 | 一区二区免费 | 亚洲高清成人 | 日韩视频在线观看一区二区 | 成人一区二区三区在线观看 | 婷婷色综合 | 99自拍视频 | 97在线超碰 | 日韩喷潮 | 99免费在线观看视频 | 美日韩免费视频 | 欧美一级全黄 | 亚洲aⅴ | 成人性视频免费网站 | 亚洲精品一区二区三区 | 羞羞网站在线观看 | 性国产丰满麻豆videosex | 成人午夜在线 | 久久天天躁狠狠躁夜夜躁2014 | 日韩一区二区视频 | 成人在线精品视频 | 男人阁久久| 天天躁日日躁狠狠躁白人 | 久久精品免费 | 久久久久久久国产 | 欧美一区在线视频 | 成av在线| 视频一二三区 | 射欧美| 亚洲精品国产第一综合99久久 | 国产第1页| 亚洲一区二区三区四区五区中文 | 欧美三区视频 | 一级一级一级毛片 | 99久久精品国产一区二区三区 |