范例:
RatioLayout
TODO 包裹ImageView,适配宽度或高度,解决宽度或高度二次缩放问题 public class RatioLayout extends FrameLayout { private static final String TAG = "RatioLayout"; private static final int MODE_NONE = 0; //固定宽度 private static final int MODE_WIDTH = 1; //固定高度 private static final int MODE_HEIGHT = 2; //固定高度 private int mRelative = MODE_NONE; // 图片缩放比例 float mRatio; public RatioLayout(Context context) { super(context); } public RatioLayout(Context context, AttributeSet attrs) { super(context, attrs); // 自定义属性,设置mRelative,mRatio TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout); mRatio = array.getFloat(R.styleable.RatioLayout_mRatio, 2.42f); mRelative = array.getInt(R.styleable.RatioLayout_mRelative, MODE_NONE); array.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 1.获取宽高信息 int width = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); // 测量的3种模式: exactly, at_most, unspecified // 宽度固定,重新测量高度(高度被缩放了) if (mRelative == MODE_WIDTH && widthMode == MeasureSpec.EXACTLY) { // 2.测量孩子 int totalHeight = (int) (width / mRatio); int totalHeightSpec = MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY); // 孩子的最终真实宽高 int childWidth = width - getPaddingLeft() - getPaddingRight(); int childHeight = totalHeight - getPaddingTop() - getPaddingBottom(); // int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY); // int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY); // childrenView不需要减去padding值 measureChildren(widthMeasureSpec, totalHeightSpec); // 3.决定自己的宽高 setMeasuredDimension(width, totalHeight ); // 高度固定,重新测量宽度(宽度被缩放了) } else if (mRelative == MODE_HEIGHT && heightMode == MeasureSpec.EXACTLY) { // 2.测量孩子 int totalWidth = (int) (height * mRatio); int totalWidthSpec = MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY); // 孩子的最终真实宽高 int childWidth = totalWidth - getPaddingLeft() - getPaddingRight(); int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY); int childHeight = height - getPaddingTop() - getPaddingBottom(); int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY); measureChildren(childWidthSpec, childHeightSpec); // 3.决定自己的宽高 setMeasuredDimension(totalWidth, height); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } }
RatioLayout