1. 程式人生 > >Android中Recyclerview使用13----實現瀑布流遇到的各種問題(item移動,載入更多圖片閃爍,以及定製各種型別Header和Footer)

Android中Recyclerview使用13----實現瀑布流遇到的各種問題(item移動,載入更多圖片閃爍,以及定製各種型別Header和Footer)

功能:圖片瀑布流

問題1:如何保持已顯示過的imageview的尺寸

解決方法:定義一個HashMap<Integer, Float> indexMap = new HashMap<Integer, Float>();用來儲存已顯示過的ImageView尺寸,顯示時直接取其比例即可

程式碼:onBindItemView(),呼叫resizeItemView(itemViewHolder.frontCoverImage, getScaleType(position));

  1. privatefloat getScaleType(int position) {  
  2.         if (!indexMap.containsKey(position)) {  
  3.             float scaleType;  
  4.             if (hasHeader()) {  
  5.                 if (position == 1) {  
  6.                     scaleType = SIZE_SCALE_01;  
  7.                 } elseif (position == 2) {  
  8.                     scaleType = SIZE_SCALE_02;  
  9.                 } else
     {  
  10.                     scaleType = Utils.getRandomInt() % 2 == 0 ? SIZE_SCALE_01 : SIZE_SCALE_02;  
  11.                 }  
  12.             } else {  
  13.                 if (position == 0) {  
  14.                     scaleType = SIZE_SCALE_01;  
  15.                 } elseif (position == 1) {  
  16.                     scaleType = SIZE_SCALE_02;  
  17.                 } else {  
  18.                     scaleType = Utils.getRandomInt() % 2 == 0 ? SIZE_SCALE_01 : SIZE_SCALE_02;  
  19.                 }  
  20.             }  
  21.             indexMap.put(position, scaleType);  
  22.         }   
  23.         return indexMap.get(position);  
  24.     }  
  25.     privatevoid resizeItemView(ImageView frontCoverImage, float scaleType) {  
  26.         LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frontCoverImage.getLayoutParams();  
  27.         params.width = screenWidth / 2;  
  28.         params.height = (int) (params.width / scaleType) - Utils.dp2px(context, 8);  
  29.         frontCoverImage.setLayoutParams(params);  
  30.     }<pre name="code"class="java">privatevoid resizeItemView(ImageView frontCoverImage, float scaleType) {  
  31.         LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frontCoverImage.getLayoutParams();  
  32.         params.width = screenWidth / 2;  
  33.         params.height = (int) (params.width / scaleType) - Utils.dp2px(context, 8);  
  34.         frontCoverImage.setLayoutParams(params);  
  35.     }  

以上解決了滑動過程中的item移動,但是RecyclerView滑動到頂部時仍會出現移動問題,這是由於item重用,並且要保持滿屏造成的

問題2:RecyclerView滑動到頂部時仍會出現移動問題

解決方法:

  1. final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);  
  2.         //RecyclerView滑動過程中不斷請求layout的Request,不斷調整item見的間隙,並且是在item尺寸顯示前預處理,因此解決RecyclerView滑動到頂部時仍會出現移動問題
  3.         layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);  
  4.         mRecyclerView.setLayoutManager(layoutManager);  
  5.         mRecyclerView.addItemDecoration(new DividerGridItemDecoration(getContext()));  
  6.         mRecyclerView.setPadding(0000);  
  7.         mRecyclerView.addOnScrollListener(new OnScrollListener() {  
  8.             @Override
  9.             publicvoid onScrollStateChanged(RecyclerView recyclerView, int newState) {  
  10.                 super.onScrollStateChanged(recyclerView, newState);  
  11.                 layoutManager.invalidateSpanAssignments();  
  12.             }  
  13.         });  


以上解決了item移動的各種問題

問題3:瀑布流載入更多用notifyDataSetChanged()重新整理圖片閃爍

原因:notifyDataSetChanged()會導致整個itemview重新整理,已經測試:相同position重新整理其itemview是不同的物件,例如,重新整理後,position為12的用了position為13的itemview,再次重新整理時,又用了position為10的itemview,這樣次position上對應的itemview的ImageView就會在重設size時發生閃爍,此現象是可以用肉眼看到的。

解決方法:

用notifyItemRangeInserted()進行區域性重新整理,這樣原先的itemview就不會重繪