文章

实现正方形控件的几种方式

实现正方形控件的几种方式

实现正方形控件的几种方式

[toc]

方法 1

1
2
3
4
5
6
7
8
9
10
11
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));  

  // Children are just made to fill our space.  
   int childWidthSize = getMeasuredWidth();  
   int childHeightSize = getMeasuredHeight();  
  //高度和宽度一样  
  heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY);  
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
}

方式 2

1
2
3
4
5
6
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
    //重写此方法后默认调用父类的onMeasure方法,分别将宽度测量空间与高度测量空间传入
    // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

方式 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 */
public class SquareLayout extends FrameLayout {
    private int orientation = LinearLayout.HORIZONTAL;

    public SquareLayout(Context context) {
        super(context);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SquareLayout, defStyleAttr, 0);
        int index = typedArray.getInt(R.styleable.SquareLayout_square_orientation, -1);
//        int index = MyInputConnectionWrapper.getInt(com.android.internal.R.styleable.LinearLayout_orientation, -1);
        if (index >= 0) {
            setOrientation(index);
        }

        typedArray.recycle();
    }

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

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

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(orientation == LinearLayout.HORIZONTAL ? widthMeasureSpec : heightMeasureSpec, orientation == LinearLayout.HORIZONTAL ? widthMeasureSpec : heightMeasureSpec);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //核心就是下面这块代码块啦
//        int width = orientation == LinearLayout.HORIZONTAL ? getMeasuredWidth() : getMeasuredHeight();
        if (orientation == LinearLayout.HORIZONTAL) {
            setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
        } else {
            setMeasuredDimension(heightMeasureSpec, heightMeasureSpec);
        }
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        ViewGroup.LayoutParams lp = getLayoutParams();
        lp.height = orientation == LinearLayout.HORIZONTAL ? width : width;
        lp.width = orientation == LinearLayout.HORIZONTAL ? width : height;
        setLayoutParams(lp);
    }

    public void setOrientation(int orientation) {
        this.orientation = orientation;
    }
}

官方 (推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 */
public class SquareFrameLayout extends FrameLayout {

    public SquareFrameLayout(Context context) {
        super(context);
    }

    public SquareFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    public SquareFrameLayout(Context context, AttributeSet attrs,
            int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthSize == 0 && heightSize == 0) {
            // If there are no constraints on size, let FrameLayout measure
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

            // Now use the smallest of the measured dimensions for both dimensions
            final int minSize = Math.min(getMeasuredWidth(), getMeasuredHeight());
            setMeasuredDimension(minSize, minSize);
            return;
        }

        final int size;
        if (widthSize == 0 || heightSize == 0) {
            // If one of the dimensions has no restriction on size, set both dimensions to be the
            // on that does
            size = Math.max(widthSize, heightSize);
        } else {
            // Both dimensions have restrictions on size, set both dimensions to be the
            // smallest of the two
            size = Math.min(widthSize, heightSize);
        }

        final int newMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
        super.onMeasure(newMeasureSpec, newMeasureSpec);
    }
}
本文由作者按照 CC BY 4.0 进行授权