欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義ViewGroup實現(xiàn)堆疊頭像的點贊Layout

 更新時間:2017年10月20日 09:30:46   作者:FlowLeaf  
這篇文章主要介紹了 Android自定義ViewGroup實現(xiàn)堆疊頭像的點贊Layout,具有一定的參考價值,感興趣的小伙伴們可以參考一下

簡介

這里寫圖片描述

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

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

這個實現(xiàn)起來不難,自定義ViewGroup,關(guān)鍵重寫onLayout方法。

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

實現(xiàn)

自定義屬性

屬性名 說明 默認值
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;//當(dāng)前行總寬度
    int rawHeight = 0;// 當(dāng)前行高

    int rowIndex = 0;//當(dāng)前行位置
    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;
      }

      //這里調(diào)用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;//當(dāng)前行位置
    View childView;
    for( int w = 0, count = getChildCount(); w < count; w++ ){
      childView = getChildAt(w);
      if(childView.getVisibility() == GONE) continue;

      MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
      // 如果加上當(dāng)前子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方式去設(shè)置數(shù)據(jù)源。

下載

https://github.com/LineChen/PileLayout

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論