前言
GridLayoutManager網格布局管理,支持RecyclerView成為網格布局的關鍵。可能很多人在了解網格布局列表會聯想到GridView。簡單網格布局的情況下推薦使用GridView,因為更為簡單。但是在復雜布局的情況下就更推薦使用RecyclerView來實現網格布局。因為RecyclerView功能更加強大且靈活。
簡單使用GridLayoutManager
RecyclerView的其他代碼就不展示了,這些代碼在我的博客里有很多,這里說明我們關注的GridLayoutManager部分代碼。如下將GridLayoutManager設置到RecyclerView,實現一個4列的網格列表。
GridLayoutManager layoutManager = new GridLayoutManager(this, 4);//第二個參數為網格的列數 mRecyclerView.setLayoutManager(layoutManager);
注意!如果你發現你的item填不滿一行或者一行的左右兩邊還有很多空間,其實是你的item的布局寬度不是match_parent導致的
效果圖:
改變指定位置item的列尺寸
假設現在有需求,希望第1個item,單獨占據一行的全部空間。我們可以使用setSpanSizeLookup方法實現這一需求:
代碼:
GridLayoutManager layoutManager = new GridLayoutManager(this, 4); mRecyclerView.setLayoutManager(layoutManager); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position == 0){ return 4; } return 1; } });
使用返回的position來判斷指定位置的item,然后返回占據的列數。請注意!這里一開始特別容易錯誤理解,這里的返回值其實是表達我們希望這個item占據多少位置。在上面實例GridLayoutManager第二個參數我們寫了4,就代表最多的列數只有4列,如果我們希望指定item占據整行就要返回 4 , 然后剩下的其他item只占據1位。另外這里不能返回大於我們實例設置的列數,如果我這里返回5,就會出現報錯。
效果圖:
在舉一個例子幫助理解,我們希望第一個item只占據2列,最后一個item占滿一行全部列數,代碼如下:
GridLayoutManager layoutManager = new GridLayoutManager(this, 4);//第二個參數為網格的列數 mRecyclerView.setLayoutManager(layoutManager); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position == 0) { return 2; } if (position == mRecyclerView.getAdapter().getItemCount() - 1) { return 4; } return 1; } });
請注意,這里別使用mRecyclerView.getChildCount()來獲取item的數量,在getSpanSize方法調用時,RecyclerView其實還在onMeasure,獲取的item數量還在增值。
效果圖 :
隨時修改列數
代碼:
mGridLayoutManager = new GridLayoutManager(this, count); mRecyclerView.setLayoutManager(mGridLayoutManager); mRecyclerView.setAdapter(mRecyclerViewAdapter); mAddCountBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mGridLayoutManager.setSpanCount(++count); } });
效果圖:
禁止滾動
有時候我們會需要某個方向沒有滾動功能
textList.setLayoutManager(new GridLayoutManager(context, 5){ @Override public boolean canScrollHorizontally() { //禁止水平滾動 return false; } @Override public boolean canScrollVertically() { //禁止垂直滾動 return false; } });
End