下面介个方法都是复写 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);
}
}