簡體   English   中英

Android在RecyclerView上猛撲動作

[英]Android fling actions on a RecyclerView

我最近在玩RecyclerView和Android 5+中的ViewHolder概念。 適配器實現處理相當大的數據集(即約60 000個項目),這些數據集是通過onBindViewHolder(...)調用從互聯網上請求的。 網絡請求由凌空庫處理,響應代表用於填充視圖持有者的數據模型。

現在,當快速移動(即以一定速度運動,而不是用戶觸摸設備並在屏幕上緩慢移動的滑動速度)時,在適配器中的所有位置都需要調用onBindViewHolder ,這對大多數觀看者來說不是一件好事由於動畫速度太快而無法顯示。 例如,如果用戶在幾秒鍾內從位置5滑動到300,大多數視圖將無法讀取,但將調用bind方法。 由於適配器從網絡獲取數據模型-發出了很多請求,大多數請求都沒有用,並且空洞處理只是延遲了用戶可以觀察到的位置300附近的請求處理。

如何解決這個僅請求可見職位的問題? 我的第一種方法是在排球處理隊列中確定請求的優先級。 確實,這並不能解決很多問題,因為每個網絡請求都以不同的順序處理。 我的第二種方法是在添加新請求時取消所有現有請求。 從我的角度來看,它對我來說不是很好,從設計的角度來看,我不喜歡這種解決方案。

那么,我真正的問題是,您將如何處理這個問題?

是的,我設法通過保持每個適配器位置的狀態來解決問題。 RecyclerView.Adapter具有兩個方法onViewAttachedToWindow(VH holder)onViewDetachedFromWindow(VH holder)當用戶即將看到視圖或將視圖刪除以致用戶看不到時發出信號。

我創建了一個簡單的單例類,以保持每個適配器位置的狀態:

import java.util.HashSet;
import java.util.Set;

/**
 * Created by fauri on 14/06/2015.
 */
public class ViewHolderState {
    private static final ViewHolderState ourInstance = new ViewHolderState();
    private Set<Integer> recycled = new HashSet<>();

    private ViewHolderState() {
    }

    public static ViewHolderState getInstance() {
        return ourInstance;
    }

    public void addRecycledView(int position) {
        recycled.add(position);
    }

    public void removeRecycledView(int position) {
        recycled.remove(position);
    }

    public boolean isViewRecycled(int position) {
        return recycled.contains(position);
    }

    public void clearAll() {
        recycled.clear();
    }
}

在適配器類中:

 private ViewHolderState viewHolderState = ViewHolderState.getInstance();


 @Override
    public void onViewDetachedFromWindow(CardViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        viewHolderState.addRecycledView(holder.getAdapterPosition());
    }

    @Override
    public void onViewAttachedToWindow(CardViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        viewHolderState.removeRecycledView(holder.getAdapterPosition());
    }

這只是為了保持每個適配器位置的狀態。 現在,在觸發網絡調用的業務邏輯中,您只需要獲取單例實例並檢查isViewRecycled(int adapterPosition) 如果視圖被回收,則無需進行網絡調用。

當然,這是一個簡單的解決方案。 可以通過添加線程安全性(例如,使用Collection.synchronizedSet(...)或使方法同步)或僅使用其他模式來改進代碼。 Java專家不會真正挖掘單例模式。

無論如何,一般的想法是利用onViewAttachedToWindowonViewDetachFromWindow

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM