package me.daemon;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import me.daemon.library.R;

/**
 * 自适应标签容器<br/>
 * Created by daemon on 2016/11/8.
 */
public class AdaptiveLabelGroup extends ViewGroup {

    /**
     * 水平间距
     */
    private int horizontalDividerSize = 0;

    /**
     * 垂直间距
     */
    private int verticalDividerSize = 0;

    public AdaptiveLabelGroup(Context context) {
        super(context);

        init(context, null, 0, 0);
    }

    public AdaptiveLabelGroup(Context context, AttributeSet attrs) {
        super(context, attrs);

        init(context, attrs, 0, 0);
    }

    public AdaptiveLabelGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init(context, attrs, defStyleAttr, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public AdaptiveLabelGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        init(context, attrs, defStyleAttr, defStyleRes);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.AdaptiveLabelGroup, defStyleAttr, defStyleRes);

        final int hDividerSize = a.getDimensionPixelSize(R.styleable.AdaptiveLabelGroup_horizontal_divider_size, 0);
        if (hDividerSize != 0) {
            setHorizontalDividerSize(hDividerSize);
        }

        final int vDividerSize = a.getDimensionPixelSize(R.styleable.AdaptiveLabelGroup_vertical_divider_size, 0);
        if (vDividerSize != 0) {
            setVerticalDividerSize(vDividerSize);
        }

        a.recycle();
    }

    public void setHorizontalDividerSize(final int horizontalDividerSize) {
        this.horizontalDividerSize = horizontalDividerSize;
        requestLayout();
        invalidate();
    }

    public void setVerticalDividerSize(final int verticalDividerSize) {
        this.verticalDividerSize = verticalDividerSize;
        requestLayout();
        invalidate();
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
        if (lp instanceof LayoutParams) {
            return new LayoutParams((LayoutParams) lp);
        } else if (lp instanceof MarginLayoutParams) {
            return new LayoutParams((MarginLayoutParams) lp);
        } else {
            return new LayoutParams(lp);
        }
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

        final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        final int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        // 当前总高度
        int totalHeight;

        if (MeasureSpec.EXACTLY == heightSpecMode) {
            totalHeight = heightSpecSize;
        } else {
            final int count = getChildCount();

            // 一行View总宽度，初始为容器左padding
            int width = getPaddingLeft();

            // 当前行高度，以该行View中高度最高的为准
            int rowHeight = 0;

            // 总高度初始加上容器顶部padding
            totalHeight = getPaddingTop();

            for (int i = 0; i < count; i++) {
                final View v = getChildAt(i);
                final LayoutParams lp = (LayoutParams) v.getLayoutParams();
                final int childW = v.getMeasuredWidth();
                final int childH = v.getMeasuredHeight();

                if (width + childW + lp.leftMargin + lp.rightMargin + getPaddingRight() > widthSpecSize) {
                    // 总宽度超过容器宽度，总高度加上垂直间距及当前行高度，换行，重置行高、行宽
                    totalHeight += verticalDividerSize + rowHeight;
                    rowHeight = 0;
                    width = getPaddingLeft();
                }

                // 行宽加上垂直间距、当前View宽度及左右margin
                width += horizontalDividerSize + childW + lp.leftMargin + lp.rightMargin;

                if (rowHeight < childH + lp.topMargin + lp.bottomMargin) {
                    // 行高取当前行中View高度+上下margin最大值
                    rowHeight = childH + lp.topMargin + lp.bottomMargin;
                }
            }

            // 计算完成，总高度加上最后一行的高度
            totalHeight += rowHeight;

            // 总高度加上容器底部padding
            totalHeight += getPaddingBottom();
        }

        setMeasuredDimension(widthSpecSize, totalHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();

        int width = getPaddingLeft();

        int rowHeight = 0;

        int totalHeight = getPaddingTop();

        final int measuredWidth = getMeasuredWidth();

        for (int i = 0; i < count; i++) {
            final View v = getChildAt(i);
            final LayoutParams lp = (LayoutParams) v.getLayoutParams();
            final int childW = v.getMeasuredWidth();
            final int childH = v.getMeasuredHeight();

            if (width + childW + lp.leftMargin + lp.rightMargin + getPaddingRight() > measuredWidth) {
                totalHeight += verticalDividerSize + rowHeight;
                rowHeight = 0;
                width = getPaddingLeft();
            }

            v.layout(width + lp.leftMargin, totalHeight + lp.topMargin,
                    width + lp.leftMargin + childW, totalHeight + lp.topMargin + childH);

            width += horizontalDividerSize + childW + lp.leftMargin + lp.rightMargin;

            if (rowHeight < childH + lp.topMargin + lp.bottomMargin) {
                rowHeight = childH + lp.topMargin + lp.bottomMargin;
            }
        }
    }

    public static class LayoutParams extends MarginLayoutParams {

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams p) {
            super(p);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(LayoutParams source) {
            super(source);
        }
    }
}

@@ -1346,32 +1346,64 @@
  defStyleRes) %7B%0A
+        if(null != attrs) %7B%0A    
         final Ty
@@ -1447,16 +1447,20 @@
 ibutes(%0A
+    
         
@@ -1535,32 +1535,36 @@
 eRes);%0A%0A        
+    
 final int hDivid
@@ -1660,24 +1660,28 @@
 0);%0A        
+ 
+   
 if (hDivider
@@ -1685,32 +1685,36 @@
 derSize != 0) %7B%0A
+    
             setH
@@ -1741,32 +1741,36 @@
 (hDividerSize);%0A
+    
         %7D%0A%0A     
@@ -1764,32 +1764,36 @@
      %7D%0A%0A        
+    
 final int vDivid
@@ -1887,24 +1887,28 @@
 0);%0A        
+    
 if (vDivider
@@ -1932,16 +1932,20 @@
         
+  
+  
 setVerti
@@ -1974,35 +1974,43 @@
 rSize);%0A        
-%7D%0A%0A
+    %7D%0A%0A    
         a.recycl
@@ -2010,24 +2010,34 @@
 .recycle();%0A
+        %7D%0A
     %7D%0A%0A    p

修复NPE BUG