鍍金池/ 問(wèn)答/Android  HTML/ 請(qǐng)問(wèn),如何獲取到RecyclerView中每個(gè)item在屏幕上顯示的時(shí)長(zhǎng)

請(qǐng)問(wèn),如何獲取到RecyclerView中每個(gè)item在屏幕上顯示的時(shí)長(zhǎng)

有個(gè)需求,要能獲取到RecyclerView中每個(gè)item在屏幕上顯示的時(shí)長(zhǎng),哪位大神知道

回答
編輯回答
情皺
只要找到View(ViewHolder)顯示隱藏的調(diào)用函數(shù),就能計(jì)算出每個(gè)View(ViewHolder)的顯示時(shí)長(zhǎng)。

很幸運(yùn)的時(shí),RecyclerView提供了這樣的接口函數(shù),而且還是兩對(duì)接口函數(shù):

1.RecyclerView#Adapter提供了一對(duì)函數(shù):onViewAttachedToWindow(VH)onViewDetachedFromWindow(VH)

public abstract static class Adapter<VH extends ViewHolder> {
    ... ...
    
    /**
     * Called when a view created by this adapter has been attached to a window.
     *
     * <p>This can be used as a reasonable signal that the view is about to be seen
     * by the user. If the adapter previously freed any resources in
     * {@link #onViewDetachedFromWindow(RecyclerView.ViewHolder) onViewDetachedFromWindow}
     * those resources should be restored here.</p>
     *
     * @param holder Holder of the view being attached
     */
    public void onViewAttachedToWindow(VH holder) {
    }

    /**
     * Called when a view created by this adapter has been detached from its window.
     *
     * <p>Becoming detached from the window is not necessarily a permanent condition;
     * the consumer of an Adapter's views may choose to cache views offscreen while they
     * are not visible, attaching and detaching them as appropriate.</p>
     *
     * @param holder Holder of the view being detached
     */
    public void onViewDetachedFromWindow(VH holder) {
    }

    ... ...
}

2.RecyclerView提供了OnChildAttachStateChangeListener接口:

public interface OnChildAttachStateChangeListener {

    /**
     * Called when a view is attached to the RecyclerView.
     *
     * @param view The View which is attached to the RecyclerView
     */
    void onChildViewAttachedToWindow(View view);

    /**
     * Called when a view is detached from RecyclerView.
     *
     * @param view The View which is being detached from the RecyclerView
     */
    void onChildViewDetachedFromWindow(View view);
}

上面的兩對(duì)接口函數(shù),根據(jù)情況選用其一就好了,基本實(shí)現(xiàn)邏輯:

  1. 設(shè)置兩個(gè)變量,一個(gè)用來(lái)保存AttachedToWindow被調(diào)用時(shí)的時(shí)間戳,一個(gè)用來(lái)保存顯示的總時(shí)長(zhǎng)
  2. DetachedFromWindow被調(diào)用時(shí),計(jì)算與AttachedToWindow的時(shí)間戳差值,并將AttachedToWindow的時(shí)間戳清零,然后總時(shí)長(zhǎng)加上這個(gè)差值
  3. AttachedToWindow后,DetachedFromWindow未被調(diào)用前,只需獲取當(dāng)前系統(tǒng)時(shí)間戳,然后計(jì)算與AttachedToWindow的時(shí)間戳差值,再加上總時(shí)長(zhǎng),就是總時(shí)長(zhǎng)
2018年4月3日 22:36
編輯回答
詆毀你

可以使用HashMap記錄, 在bind時(shí), position 為key, value為一個(gè)entity, 含start和end兩個(gè)成員,設(shè)置一個(gè)標(biāo)記, 記錄是否已經(jīng)記錄過(guò)時(shí)間。

2017年2月25日 17:02
編輯回答
局外人

嘗試使用,這個(gè)監(jiān)聽(tīng):

ViewTreeObserver.OnGlobalLayoutListener

參考:

2018年5月22日 07:19
編輯回答
骨殘心

第一次顯示的時(shí)候獲取系統(tǒng)時(shí)間來(lái)作為初始時(shí)間,再次顯示的時(shí)候已當(dāng)前系統(tǒng)時(shí)間減去第一次的時(shí)間

2017年3月10日 01:31