1. 程式人生 > >RecyclerView載入圖片滑動卡頓

RecyclerView載入圖片滑動卡頓

在專案上線,遇到了一個讓人很難受的問題,主介面滑動卡頓,有的手機情況情況還好,但是部分手機很糟糕,這個問題說實話讓人很蛋疼。

RecyclerView相比較listview與gridview具有更多的活動性。所以在這個介面我使用萬能重新整理控制元件XRefreshView來包裹RecyclerView,item各有不同,第一個banner、第二個跑馬燈效果、第三個gridview、第四個View、第五個view、後面的效果就是列表效果啦。

這種卡頓很多情況都是事件衝突所引起的,我的這個上面banner、跑馬燈、gridview這些都可能存在滑動衝突,然後我把這些item一個個註釋掉,但是效果並沒有變好,這樣說明我沒有找到問題。

我用的圖片載入框架是Fresco(3級快取設計,合理運用好了裝置本身的記憶體區域,圖片管理過程非常高效,使得前端體驗更加流暢,也較有效地避免了常見記憶體問題的產生。),他只加載當前展示區域的圖片,在系統不足時,自己會去回收那些沒有使用的記憶體。

在懷著不信的態度去嘗試,是不是圖片載入的消耗記憶體。註釋這行程式碼後,果然成功了。0.0(很尷尬的找了那麼久,測試環境圖片解析度都很小,正式環境圖片解析度達到了4000*3000換算下來載入一張圖片記憶體需要消耗近30多M)

這裡我相信大家知道了,是什麼原因造成我介面的卡頓。圖片載入消耗太多的記憶體,這樣的情況輕者造成卡頓(我這個介面暫時只有幾條資料),載入過多就會出現oom。

說了這麼多,應該大家也知道怎麼處理了。但是我還是要記錄下來,萬一我自己忘記了呢^-^。

解決這個最好的辦法就是將伺服器返回給我們的圖片轉換成bitmao進行壓縮。

但是呢!哼哼,我不需要,因為Fresco提供了一個圖片壓縮的方法,具體如下:

public class ImageUtils {

    private static Context mContext;

    public ImageUtils(Context mContext) {
        this.mContext = mContext;
    }

    public static void setImg(SimpleDraweeView mImg, String url) {
        Uri uri = Uri.parse(url);

        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setResizeOptions(new ResizeOptions(dp2px(140), dp2px(90)))
                .build();

        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setOldController(mImg.getController())
                .setControllerListener(new BaseControllerListener<ImageInfo>())
                .setImageRequest(request).build();
        mImg.setController(controller);
    }

    static int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources()
                .getDisplayMetrics());
    }
}

事實證明只是比開始好一點點,經過查詢還有這些優化方式:

  1. 佈局儘量減小巢狀;
  2. RecyclerView間隔線最好寫在item裡面;
  3. Fresco圖片格式RGB_8888(預設)改為RGB_565;
  4. 裁剪圖片與壓縮圖片;
  5. 滑動完畢後進行程式碼載入;
RecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {

        }else {

        }
    }
})

RecyclerView.SCROLL_STATE_IDLE //空閒狀態

RecyclerView.SCROLL_STATE_FLING //滾動狀態

RecyclerView.SCROLL_STATE_TOUCH_SCROLL //觸控後狀態

Glide記載圖片:

 if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            Glide.with(mContext).resumeRequests();
        }else {
            Glide.with(mContext).pauseRequests();
        }

Fresco載入圖片:

 if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            Fresco.getImagePipeline().resume();
        }else {
            Fresco.getImagePipeline().pause();
        }

RecyclerView滑動事件監聽載入--------------點選這裡