1. 程式人生 > >RecyclerView區域性重新整理的坑

RecyclerView區域性重新整理的坑

話說有圖有真相,首先來對比一下區域性重新整理前後的效果:

優化之前的效果:


優化之後的效果:


可以看到,優化之後,列表中的這張大圖不在有一閃一閃亮晶晶的效果了!

那麼,這是如何做到的呢?這是本文的重點,本文的大綱主要包括:
  1. 分析為什麼會閃一下

  2. 對分析的可能造成閃動的問題進行解決

  3. 驗證是否解決

一、為什麼會閃一下呢?

我們的需求是大家已經看到了,點選打分,彈出一個對話方塊,點選一個分數,這時候,通過一些列複雜的轉換(當然不是本文的論述的重點),這時候到了要更新列表項了,如是很自然,我們會這麼做:


因為,操作的那個列表項你是知道他的position,所以你可以這麼做,(當然,我之前是直接notifyDataSetChanged的,這個會照成所以不不要的item也會重新整理)然而,閃動還是出現了,那麼我開始懷疑:
  1. 流傳甚為廣泛的一種說法,imageView的寬高不固定導致的(wrap_content)?

  2. 這個是RecyclerView自帶的更新動畫效果導致的?

  3. 這個是因為圖片載入框架(glide 的 animte)的動畫效果導致的?

  4. getView中(RecyclerView中是onBindViewHolder)載入圖片的時候,設定一個tag,當發現這個imageView的tag和之前的tag一致時就不載入

二、嘗試

1、對於第一種,我的做法是自己寫了一個自定義的imageView,重寫omMeasure方法,如下:


因為我們的這個列表項中的圖片是(高=寬)的,因此,我才這麼寫,這樣寫也有一個好處,不用在onBindViewHolder中去動態的計算出高度,然後在已layoutParm的方式設定給imageView,相信不少小夥伴都做過了吧!


然而,遺憾的是,他並沒有解決閃一下的問題!此時這個閃動的原因顯然不在這裡,但是這裡做的,可以保留下來。

2、對於第二種說法,我參考了這裡http://stackoverflow.com/questions/29331075/recyclerview-blinking-after-notifydatasetchanged

的做法:


以及也嘗試了這種


然而,那種漸變的閃動消失了,但是,取而代之的是一種更加不可接受的閃動,這裡就不用gif展示了,因此原因也並不在此處。

3、對於對三種說法,我也去嘗試了一下將glide載入改為:


然而得到的依然是一個失望的結果,依然沒有解決閃動的問題,原因也不在此處。


4、那麼,就剩下最後一個猜測了,那麼會不會是它呢?那就試試吧,於是程式碼改為:


這裡的做法其實就是設定Tag,那麼是騾子是馬,拉出來溜溜吧,結果更加令人髮指,如圖:

好吧,此時已經有點崩潰了,顯然這個也不是我要的結果,那麼此時是否應該在靜下來想一想,自己對於可能的幾種原因做過的一些對策,是否有哪裡遺漏了。經過思考,發現並沒有!!那麼一定是還有其他的原因,沒有考慮到!

還是去翻一翻RecyclerView的api吧,我注意到了這個api:



可以看到這裡有一個payload的引數,use null to identify a "full" update這是說如果傳null就是全部更新,回過頭去看一看我們之前的呼叫方式:

看一下原始碼,發現


實際上,payload這個引數就是傳的null,那也就是說如果傳一個不為null的引數,就可以對列表項中的具體控制元件更新了?

http://stackoverflow.com/questions/33176336/need-an-example-about-recyclerview-adapter-notifyitemchangedint-position-objec

我瞭解到這個方法的使用方式是這樣的:


然來,onBindViewHolder有這麼一個過載方式,如是我也這麼做了,在下面這個過載中,去更新我想更新的控制元件:


然後,更新的方式變成了這種:


是騾子是馬,那就在遛一遛吧!

然而,依然是會閃一下!!!這這麼會!!!還是除錯一下吧,先過載onBindViewHolder方法有沒有被執行,一更程式碼,發現果然沒有被執行!那麼,究竟是什麼鬼?去網上查了一下,有人給出了一個解決辦法:

http://stackoverflow.com/questions/32463136/recyclerview-adapter-notifyitemchanged-never-passes-payload-to-onbindviewholde


需要重寫這個動畫,讓永遠返回true,已達到newHolder和olderHolder是同一個,然而,這真的就是我的救命稻草嗎?

那麼,是騾子是馬,拉出來溜溜吧,然而,並不是馬!!進原始碼看一看


發現其實只要我們傳入的payload不為空,那麼返回的就是true?重寫有意義嗎?顯然,我過載的onBindViewHolder方法並沒有執行的原因顯然不是這個。

那麼,到底,到底問題出在何處?會不會是XrecyclerView的問題?根據呼叫棧,我看到第一個onBindViewHolder被執行了,往上面跟,發現XrecyclerView的實現果然存在問題!


如圖,作者僅僅只實現了,不帶payload的方法,最後adapter呼叫的只有不帶paylaod的方法!所以,重寫一個吧!

最後!終於達到了想要的效果了,經過這次爬坑,選擇一個開源的框架真滴是需要慎重再慎重。

總結

實際上RecyclerView做區域性重新整理是非常容易的,其實就是使用好帶payload引數的這個notifyItemRangeChanged方法,以及override帶payload的這個onBindViewHolder方法,在onBindViewHolder中去重新整理你想更新的控制元件即可,並非是網上傳聞的那些原因,當然此處爬坑時間之長,也可能跟選用開源控制元件不當有關,所以,選擇開源控制元件,要謹慎再謹慎!

參考網站:http://wetest.qq.com/lab/view/176.html?from=adsout_qqtips_past2&sessionUserType=BFT.PARAMS.201129.TASKID&ADUIN=704934878&ADSESSION=1477046345&ADTAG=CLIENT.QQ.5497_.0&ADPUBNO=26621

相關推薦

RecyclerView區域性重新整理

話說有圖有真相,首先來對比一下區域性重新整理前後的效果: 優化之前的效果: 優化之後的效果: 可以看到,優化之後,列表中的這張大圖不在有一閃一閃亮晶晶的效果了! 那麼,這是如何做到的呢?這是本文

再說Android RecyclerView區域性重新整理那個

關鍵:public final void notifyItemChanged(int position, Object payload) RecyclerView區域性重新整理大家都遇到過,有時候還說會遇見圖片閃爍的問題。 優化之前的效果: 優化之後的

recyclerview區域性重新整理閃爍

recyclerView.setItemAnimator(new MyItemAnimator()); 使用問題發現不完美,會在cardview的陰影處有閃爍一下 http://stackoverflow.com/questions/31897469/override-animation-for-no

RecyclerView 區域性重新整理(視覺)延遲問題

今天在用RecyclerView的重新整理方法時,為了避免RecyclerView.Adapter 的 notifyDataSetChanged 方法會通知 RecyclerView 重新整理全部的可見列表項,於是使 用 RecyclerView.Adapter 的noti

RecyclerView區域性重新整理的應用場景簡單分析

RecyclerView 區域性重新整理的應用場景鞏固 今天在做通訊錄遮蔽時,由於通訊錄列表裡有兩種不同的效果展示: 1. 已經遮蔽的 item ,顯示一個按鈕“解除遮蔽” 2. 未遮蔽的 item ,顯示兩個按鈕“恢復遮蔽”和“邀請” 分析到這裡後,果

RecyclerView配合DiffUtil,資料對比,區域性重新整理

本文轉載自作者: 承香墨影,附上作者微信和公眾號 一、前言 DIffUtils 是 Support-v7:24:2.0 中,更新的工具類。因為已經更新了一段時間了,也不好說是最新更新的。 它主要是為了配合RecyclerView 使用,通過比對新、舊兩

RecyclerView配合DiffUtil區域性重新整理完整例子

廢話不多說,上來就先看效果吧。點選“模擬重新整理”按鈕完成第二、三項列表中的描述文字和下面的滾動動畫的重新整理。第二次進入直接下拉到列表底部點選“模擬重新整理”按鈕,同樣可以完成定向重新整理。這應該是我們期待的效果吧。這樣的功效就是普通的RecyclerView配合DiffU

dwz問題之頁面提交表單,僅區域性重新整理table表格

一、問題 後臺管理系統有一個頁面,點選提交按鈕提交表單時,頁面整體都重新整理了。 原則上是提交表單後,表單資訊儲存原來的,只重新整理表格。 二、經過 接下來為了解決問題,開始找dwz框架裡面區域性重新整理的功能。 一種是API呼叫方式: $('#xxID').lo

SwipeRefreshLayout+Recyclerview重新整理載入封裝

目錄 1.簡介 2.自定義的SwipeRefreshLayout 1)全域性變數和基礎方法 2)onlayout拿到RecyclerView,設定載入更多的監聽 3)其餘的判斷標準 3.Activity中的使用 4.xml佈局使用 5.介面卡和單行佈局 1.簡

iOS UITableView區域性重新整理 重新整理單個cell或section

/** * 單個cell的重新整理 */ //1.當前所要重新整理的cell,傳入要重新整理的 行數 和 組數 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; /

微信小程式從子頁面返回父頁面實現資料的區域性重新整理

問題描述 A頁面有一個儲存欄位的物件陣列items,從A頁面跳轉到B頁面,B頁面自定義欄位,並新增到items中。當返回A頁面時,顯示items的部分能夠區域性重新整理 items:[{name: '0', value: '姓名', checked: true, isNecessar

DIV區域性重新整理

<script type="text/javascript"> $(function () { setInterval(function () { $("#autore").load(location.href + " #autore")

python反爬之網頁區域性重新整理1

# ajax動態載入網頁 # 怎樣判斷一個網頁是不是動態載入的呢? # 檢視網頁原始碼,如果原始碼中沒有你要的資料,嘗試訪問下一頁,當你點選下一頁的時候,整個頁面沒有重新整理, 只是區域性重新整理了,很大的可能是ajax載入 # 遇到ajax載入,一般的解決步驟就,通過瀏覽器或者軟體抓包分析響應的請求,

RecyclerView重新整理分頁

在開發中常常使用到重新整理分頁,這裡實現一個 RecyclerView 的簡單的重新整理分頁操作,測試效果見文末,實現過程參考如下: 實現思路 載入更多資料使用到 RecyclerView 載入多種佈局,根據 ViewType 判斷載入資料 Item 還是載入 Foote

Ajax實現 頁面區域性 重新整理

 web開發中我們經常會遇到區域性重新整理頁面的需求,以前我經常使用ajax和iframe實現區域性重新整理,後來做政府的專案,對頁面的樣式要求比較多,發現使用iframe控制樣式什麼的很麻煩,所以就採用了新的辦法,就是下面我們要說的ajax配合div區域性重新整理頁面,其實很簡單,下面我

hexo next主題深度優化之加入pjax,實現區域性重新整理,讓我們的部落格上高速公路吧~~~~

特別宣告: 看不懂沒關係,往下讀,因為我寫的邏輯可能不是很清晰~ 本人原始碼在github上實在不懂的 git clone自己扣一扣,github在部落格中有連線 本人部落格mmmmmm.me 背景: 我有強迫症,遇到好的東西就想給自己整上去,在這裡想忠誠的奉勸大家一句,不要再搭

解決ajax區域性重新整理後,滾動條位置變化的問題

問題描述:網頁底部實現了點贊和收藏功能,給長篇文點贊並更新點 贊數量之後,滾動條回到網頁頂部。 修改之前: <a href="#" th:onclick="'javascript:updateNum('+${article.id}+')'" > <i clas

jquery load()方法實現區域性重新整理,多張網頁切換(li標籤實現上下頁的切換)

---學習借鑑中--- (1)父頁面插入的位置 <div  id="content" > //id為要重新整理顯示的子頁面的內容 </div> (2)父頁面顯示標籤切換不同html頁面 <ul class="userMenu"> <li

微信小程式區域性重新整理

#小程式區域性重新整理Demo 第一次發微博就發個跟小程式相關的吧。記得我自學小程式的時候是2017年,當時公司要求開發一個家政型別的小程式,可我雙眼一抹黑啊,對小程式啥都不懂,於是就去翻微信官方文件,虧得我天賦異稟、智慧超凡(哈哈哈~~你們都懂的我就是吹一吹),我帶著有趣的眼神以及深厚

jquery實現區域性重新整理Iframe

1,reload 方法,該方法強迫瀏覽器重新整理當前頁面。   語法:location.reload([bForceGet])   引數: bForceGet, 可選引數, 預設為 false,從客戶端快取裡取當前頁。true, 則以 GET 方式,從服務端取最新的頁面,