1. 程式人生 > >自定義控制元件---類似新增郵件收件人效果

自定義控制元件---類似新增郵件收件人效果

自定義控制元件:增加控制元件時會則適應高度,寬度不夠時會跳至下一行;無焦點可以控制高度,有焦點顯示最大高度。

直接上程式碼:

public class LineWrapViewGroup extends ViewGroup {

     private int lineHeight = 0;
     private int hSpacing = 0;
     private int vSpacing = 0;

     public LineWrapViewGroup(Context context) {
           super(context);
           init(context, null, 0);
     }

     public LineWrapViewGroup(Context context, AttributeSet attrs) {
           super(context, attrs);
           init(context, attrs, 0);
     }

     public LineWrapViewGroup(Context context, AttributeSet attrs, int defStyle) {
           super(context, attrs, defStyle);
           init(context, attrs, defStyle);
     }

     private void init(Context context, AttributeSet attrs, int defStyle) {

           TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LineWrapViewGroup);
           // 得到橫向間隔
           hSpacing = a.getDimensionPixelSize(R.styleable.LineWrapViewGroup_horizontal_spacing, 5);
           // 得到縱向間隔
           vSpacing = a.getDimensionPixelSize(R.styleable.LineWrapViewGroup_vertical_spacing, 5);
           a.recycle();

     }

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

           int width = MeasureSpec.getSize(widthMeasureSpec);
           int height = MeasureSpec.getSize(heightMeasureSpec) + getPaddingBottom() + getPaddingTop();

           int xPos = getPaddingLeft();
           int yPos = getPaddingTop();

           int lineHeight = 0;

           for (int index = 0; index < getChildCount(); index++) {

                final View child = getChildAt(index);

                LayoutParams lp = child.getLayoutParams();
                // 算出子View寬的MeasureSpec值
                int wSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.AT_MOST);
                // 算出子View高的MeasureSpec值
                int hSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.AT_MOST);

                // measure
                child.measure(wSpec, hSpec);

                int childW = child.getMeasuredWidth();
                int childH = child.getMeasuredHeight();

                lineHeight = Math.max(lineHeight, childH + vSpacing);

                if (xPos + childW > width) {
                     xPos = getPaddingLeft();
                     yPos += lineHeight;
                }
                xPos += childW + hSpacing;

           }
           this.lineHeight = lineHeight;

           // 對高度期望值沒有限制

           /*
            * 計數,兩次更新後顯示兩個
            */
           if (index < 2) {
                height = yPos + lineHeight;
                appointHeight = height;
           } else {
                height = appointHeight;
           }

           /*
            * 控制高度
            */
           if (height > heightCount) {
                index++;
           } else if (yPos + lineHeight < height) {
                index--;
           } else if (height == 0) {
                index = 0;
           }

           heightCount = yPos + lineHeight;
           if (settingHeight) {
                height = appointHeight;
           } else {
                height = heightCount;
           }

           // 設定ViewGroup寬高值
           setMeasuredDimension(width, height);

     }

     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
           final int count = getChildCount();
           final int width = r - l;
           int xpos = getPaddingLeft();
           int ypos = getPaddingTop();
           // 設定每一個子View的位置,左上角xy座標與右下角xy座標確定View的位置
           for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.getVisibility() != GONE) {
                     final int childw = child.getMeasuredWidth();
                     final int childh = child.getMeasuredHeight();
                     if (xpos + childw > width) {
                           xpos = getPaddingLeft();
                           ypos += lineHeight;
                     }
                     child.layout(xpos, ypos, xpos + childw, ypos + childh);
                     xpos += childw + hSpacing;

                }
           }
     }

     private int index = 0; // 兩行
     private int appointHeight = 0; // 指定高度
     private int heightCount = 0; // 最大高度
     private boolean settingHeight = false; // 控制高度

     /**
      * 設定最大高度
      */
     public void getViewHeight() {
           settingHeight = false;
     }

     /**
      * 回覆為原有高度
      */
     public void getOriginalHeight() {
           settingHeight = true;
     }

}