一RecyclerView做到QQ空間相冊布局

看什麼看!點我呀!

全棧工程師,免費入門到精通!

作者丨丶E

https://www.jianshu.com/p/c5edc5883d83

前言

效果圖:

看到這布局自然會想到用RecyclerView來做,用ItemDecoration繪制日期那條分割線,每行3列的GridLayoutManager

但是有個問題,如果不是正好3列、怎麼去控制末尾的留白呢?

我的做到思路是這樣的:

GridLayoutManager中有個setSpanSizeLookup方法,getSpanSize返回值就是控制每行有幾列的

gridLayoutManager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup(){@OverridepublicintgetSpanSize(intposition){returnsetSpanSize(position,mAdapter.getDatas());}});

不了解的可以轉至:

https://www.jianshu.com/p/675883c26ef2

也就是說使用該方法我可以控制每一行的列數、只要我再控制其長度就OK了

在數據實體中添加一個value、用來記錄當前圖片和前面差了幾個空白,從而確定留白的距離

privateintsetSpanSize(intposition,List<AlbumBean>listEntities){intcount;intd;if((position+1<listEntities.size())&&position>0){if(!listEntities.get(position).getSubId().equals(listEntities.get(position+1).getSubId())){mAdapter.getItem(position+1).value=2-(mAdapter.getItem(position).value+position)%3+mAdapter.getItem(position).value;d=2-(mAdapter.getItem(position).value+position)%3;if(d==2){count=3;}elseif(d==1){count=2;}else{count=1;}}else{mAdapter.getItem(position+1).value=mAdapter.getItem(position).value;count=1;}}elseif(position==0){if(mAdapter.getDatas().size()>1){if((!listEntities.get(position).getSubId().equals(listEntities.get(position+1).getSubId()))){mAdapter.getItem(1).value=2;count=3;}else{count=1;mAdapter.getItem(1).value=0;}}else{count=1;}}else{count=1;}returncount;}

publicclassEaseItemDecorationextendsRecyclerView.ItemDecoration{privatefinalDrawablemDivider;privateList<?extendsAlbumBean>mDatas;privatePaintmPaint;privateRectmBounds;privateintmTitleHeight;privatestaticintCOLOR_TITLE_BG=Color.parseColor("#ffffff");privatestaticintCOLOR_TITLE_FONT=Color.parseColor("#333333");privatestaticintmTitleFontSize;privateintwidth;privatestaticfinalint[]ATTRS=newint[]{android.R.attr.listDivider};publicEaseItemDecoration(Contextcontext,List<?extendsAlbumBean>datas){super();mDatas=datas;mPaint=newPaint();mBounds=newRect();finalTypedArraya=context.obtainStyledAttributes(ATTRS);mDivider=a.getDrawable(0);mTitleHeight=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,90,context.getResources().getDisplayMetrics());mTitleFontSize=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,context.getResources().getDisplayMetrics());mPaint.setTextSize(mTitleFontSize);mPaint.setAntiAlias(true);width=SmallUtil.getScreenWidth(context)/3;}publicvoidsetmDatas(List<?extendsAlbumBean>mDatas){this.mDatas=mDatas;}@OverridepublicvoidonDraw(Canvasc,RecyclerViewparent,RecyclerView.Statestate){super.onDraw(c,parent,state);finalintleft=parent.getPaddingLeft();finalintright=parent.getWidth()-parent.getPaddingRight();finalintchildCount=parent.getChildCount();for(inti=0;i<childCount;i++){finalViewchild=parent.getChildAt(i);finalRecyclerView.LayoutParamsparams=(RecyclerView.LayoutParams)child.getLayoutParams();intposition=params.getViewLayoutPosition();//我記得Rv的itemposition在重置時可能為-1.保險點判斷一下吧if(position>-1){if(position==0){drawTitleArea(c,left,right,child,params,position);}else{if(null!=mDatas.get(position).getSubId()&&!mDatas.get(position).getSubId().equals(mDatas.get(position-1).getSubId())){//不為空且跟前一個tag不一樣了,說明是新的分類,也要titledrawTitleArea(c,left,right,child,params,position);}else{}}}}}/***繪制Title區域背景和文字的方法*/privatevoiddrawTitleArea(Canvasc,intleft,intright,Viewchild,RecyclerView.LayoutParamsparams,intposition){//最先調用,繪制在最下層mPaint.setColor(COLOR_TITLE_BG);c.drawRect(left,child.getTop()-params.topMargin-mTitleHeight,right,child.getTop()-params.topMargin,mPaint);mPaint.setColor(COLOR_TITLE_FONT);mPaint.setTextSize(SmallUtil.sp2px(17));Stringdate=mDatas.get(position).getTitle();mPaint.getTextBounds(date,0,date.length(),mBounds);c.drawText(date,(width*3)/2-mBounds.width()/2,child.getTop()-params.topMargin-mTitleHeight/2,mPaint);}@OverridepublicvoidonDrawOver(Canvasc,finalRecyclerViewparent,RecyclerView.Statestate){//最後調用繪制在最上層}@OverridepublicvoidgetItemOffsets(RectoutRect,Viewview,RecyclerViewparent,RecyclerView.Statestate){super.getItemOffsets(outRect,view,parent,state);intposition=((RecyclerView.LayoutParams)view.getLayoutParams()).getViewLayoutPosition();if(position>-1&&position<mDatas.size()){if(position+1<mDatas.size()){if(null!=mDatas.get(position).getSubId()&&!mDatas.get(position).getSubId().equals(mDatas.get(position+1).getSubId())){intd=2-(mDatas.get(position).value+position)%3;if(isNewLine(position,mDatas)){outRect.set(0,mTitleHeight,width*d+mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}else{outRect.set(0,0,width*d+mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}}else{if(isNewLine(position,mDatas)){outRect.set(0,mTitleHeight,mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}else{outRect.set(0,0,mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}}}else{if(isNewLine(position,mDatas)){outRect.set(0,mTitleHeight,mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}else{outRect.set(0,0,mDivider.getIntrinsicHeight(),mDivider.getIntrinsicHeight());}}}}privatebooleanisNewLine(intposition,List<?extendsAlbumBean>mDatas){booleanisNew=false;if(position==0||position==1||position==2)returntrue;intsize=position>2?position-3:0;for(inti=size;i<position;i++){if(null!=mDatas.get(i).getSubId()&&!mDatas.get(i).getSubId().equals(mDatas.get(i+1).getSubId())){isNew=true;break;}}returnisNew;}}

完成效果:

Github地址:

https://github.com/forvv231/QQAlbum

推薦↓↓↓

?16個技術公眾號】都在這里!

涵蓋:工程師大咖、源碼共讀、工程師共讀、數據結構與算法、黑客技術和網路安全、大數據科技、編程前端、Java、Python、Web編程開發、Android、iOS開發、Linux、數據庫研發、幽默工程師等。

覺得我們「好看」的點亮它~

分享到Facebook

 


不知道如何找適合的對象?歡迎加官方LINE → Line ID:@shesay
戀愛小秘書免費一對一諮詢!
✔追蹤我的YouTube:https://www.youtube.com/@datenami
✔追蹤我的TikTok:https://www.tiktok.com/@datnami

 

配對成功的關鍵:參加實體交友活動

erose主題派對與戀愛小秘書創辦人娜米表示:「透過各種有趣的實體活動,不僅能親眼真實見到異性,也能在活動進行中讓大家很輕鬆自然的認識彼此、聊天互動,能更快速的找到適合的對象。」

結合大數據用心篩選 + 客製化條件配對

戀愛小秘書團隊已經成功替4000位以上的未婚男女配對成功,這個驚人成果背後的秘密在於「高度客製化服務」,跟每位客戶深度訪談,瞭解客戶真正的特質及需求,從「契合度」提高速配率。

訪談結果結合專屬的人格分析測驗與數據配對分析,精緻化的操作,締造高速配率!

除此之外,戀愛小秘書團隊還會定期追蹤客戶的後續狀況,目的是希望協助客戶發展長期且穩定的伴侶關係。

實名認證防造假!隱私保護最安心!

採用「實名認證」的制度,不僅是把關顧客的身份,避免已婚人士或動機不單純者的加入,更對客戶資料嚴格保密,讓客戶們能在安全且有隱私的狀況下認識另一半。

多元有趣的主題活動,豐富你的社交生活

戀愛小秘書團隊每個月都會規劃豐富多元的實體活動,從戶外踏青、娛樂遊戲、手作、料理課程到桌遊活動,希望客戶們能從歡樂的氣氛中認識彼此。

透過實體活動讓大家先有初步的接觸,然後再為會員們做「客製化」的約會安排。

另外針對想提升自身魅力的客戶,也有投資理財、形象穿搭等講座可供選擇。

追求脫單,先勇敢跨出你的第一步

許多單身者為了心中理想的對象條件,在還沒認識新朋友時,就先限制了自己。建議以認識新朋友的心態,積極參與活動,並適當的設限,才能真正為自己帶來戀愛的機會!勇敢跨出第一步吧!

♡ 現在就和戀愛小秘書娜米聊聊吧Line ID:@shesay

♡ 追蹤娜米的臉書粉絲團

她來報好康

 

SheSay 專注在 兩性、愛情等領域
建立專屬女生觀點的品牌形象
堅持「在第一時間掌握男女的時事議題」
將時下最流行的話題網羅、呈現。

馬上測算你的戀愛密碼

戀愛小秘書-娜米

單身很久?一直被分手?
從生日就看出你的戀愛疑難雜症!
娜米的戀愛數字密碼來幫你了。