实现正方形布局SquareLayout的几种方法

下面介个方法都是复写 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
方法1

@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

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

方法3

*/
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;
    }


}

我本人用第一种和第三种方法,不过都发现在某些情况下会出现毛病,第二种方法没用过

官方的方式

*/
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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值