国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義ViewGroup實現堆疊頭像的點贊Layout

2019-12-12 01:51:43
字體:
來源:轉載
供稿:網友

簡介

這里寫圖片描述

這樣的點贊列表怎么樣?之前做社區的時候也有類似的點贊列表,但是沒有這樣重疊,一個小小的改變,個人感覺逼格提高不少。

這個很有規則,就是后一個頭像會覆蓋一部分到前一個頭像上,頭像多了就像一串糖葫蘆了。

這個實現起來不難,自定義ViewGroup,關鍵重寫onLayout方法。

關于自定義控件的基礎知識可以看一看這個,整理的很詳細: https://github.com/GcsSloop/AndroidNote

實現

自定義屬性

屬性名 說明 默認值
vertivalSpace 行距 4dp
pileWidth 重疊寬度 10dp

onMeasure方法,每行的寬度不再是child的寬度和了,而是要減掉重疊部分的寬度和

@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);    //AT_MOST    int width = 0;    int height = 0;    int rawWidth = 0;//當前行總寬度    int rawHeight = 0;// 當前行高    int rowIndex = 0;//當前行位置    int count = getChildCount();    for (int i = 0; i < count; i++) {      View child = getChildAt(i);      if(child.getVisibility() == GONE){        if(i == count - 1){          //最后一個child          height += rawHeight;          width = Math.max(width, rawWidth);        }        continue;      }      //這里調用measureChildWithMargins 而不是measureChild      measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);      MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();      int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;      int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;      if(rawWidth + childWidth - (rowIndex > 0 ? pileWidth : 0)> widthSpecSize - getPaddingLeft() - getPaddingRight()){        //換行        width = Math.max(width, rawWidth);        rawWidth = childWidth;        height += rawHeight + vertivalSpace;        rawHeight = childHeight;        rowIndex = 0;      } else {        rawWidth += childWidth;        if(rowIndex > 0){          rawWidth -= pileWidth;        }        rawHeight = Math.max(rawHeight, childHeight);      }      if(i == count - 1){        width = Math.max(rawWidth, width);        height += rawHeight;      }      rowIndex++;    }    setMeasuredDimension(        widthSpecMode == MeasureSpec.EXACTLY ? widthSpecSize : width + getPaddingLeft() + getPaddingRight(),        heightSpecMode == MeasureSpec.EXACTLY ? heightSpecSize : height + getPaddingTop() + getPaddingBottom()    );  }

onLayout 每一行,第一個正常放,之后的重疊放

@Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {    int viewWidth = r - l;    int leftOffset = getPaddingLeft();    int topOffset = getPaddingTop();    int rowMaxHeight = 0;    int rowIndex = 0;//當前行位置    View childView;    for( int w = 0, count = getChildCount(); w < count; w++ ){      childView = getChildAt(w);      if(childView.getVisibility() == GONE) continue;      MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();      // 如果加上當前子View的寬度后超過了ViewGroup的寬度,就換行      int occupyWidth = lp.leftMargin + childView.getMeasuredWidth() + lp.rightMargin;      if(leftOffset + occupyWidth + getPaddingRight() > viewWidth){        leftOffset = getPaddingLeft(); // 回到最左邊        topOffset += rowMaxHeight + vertivalSpace; // 換行        rowMaxHeight = 0;        rowIndex = 0;      }      int left = leftOffset + lp.leftMargin;      int top = topOffset + lp.topMargin;      int right = leftOffset+ lp.leftMargin + childView.getMeasuredWidth();      int bottom = topOffset + lp.topMargin + childView.getMeasuredHeight();      childView.layout(left, top, right, bottom);      // 橫向偏移      leftOffset += occupyWidth;      // 試圖更新本行最高View的高度      int occupyHeight = lp.topMargin + childView.getMeasuredHeight() + lp.bottomMargin;      if(rowIndex != count - 1){        leftOffset -= pileWidth;//這里控制重疊位置      }      rowMaxHeight = Math.max(rowMaxHeight, occupyHeight);      rowIndex++;    }  }

效果圖

這里寫圖片描述

因為這個一般只會顯示一行,所以暫時沒有通過setAdapter方式去設置數據源。

下載

https://github.com/LineChen/PileLayout

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 达拉特旗| 兴义市| 灵宝市| 临潭县| 金山区| 佛山市| 桦南县| 江油市| 泸定县| 奇台县| 客服| 新民市| 赣榆县| 奈曼旗| 石柱| 开江县| 樟树市| 彰化市| 佛教| 九江县| 兴安盟| 凤庆县| 石阡县| 平安县| 临西县| 甘德县| 新河县| 聂拉木县| 鄂伦春自治旗| 龙川县| 清镇市| 正定县| 顺义区| 铜陵市| 贵溪市| 汝南县| 武威市| 丹东市| 鄂托克旗| 建湖县| 赤城县|