您的位置:首页 > 其它

自定义布局之宽高比布局的实现

2016-02-29 09:07 281 查看
最近在项目中遇到一个屏幕适配的问题,在显示图片时我在布局中宽度和高度都设置了固定的dp值,但当app运行在一些屏幕比较宽的手机上时,会出现图片宽高比不对情况,因为宽屏的手机横向的像素密度比较大,为此在网上找到一个解决方案是,定义一个可以根据图片本身宽高比来设置控件宽高的布局。实现如下

首先声明两个属性,一个是picRatio表示图片的宽高比,一个是relative表示要根据宽度按比例确定高度,还是根据高度按比例确定宽度

<resources>

<declare-styleable name="RatioLayout">
<attr name="picRatio" format="float" />
<attr name="relative">
<enum name="width" value="0" />
<enum name="height" value="1" />
</attr>
</declare-styleable>

</resources>

下面是具体的代码实现
public class RatioLayout extends FrameLayout {
private float				mPicRatio		= 0f;				// 图片的宽高比 2.43
public static final int	RELATIVE_WIDTH	= 0;				// 控件宽度固定,已知图片的宽高比,求控件的高度
public static final int	RELATIVE_HEIGHT	= 1;				// 控件高度固定,已知图片的宽高比,求控件的宽度
private int					mRelative		= RELATIVE_WIDTH;

public void setPicRatio(float picRatio) {
mPicRatio = picRatio;
}

public void setRelative(int relative) {
mRelative = relative;
}

public RatioLayout(Context context) {
this(context, null);
}

public RatioLayout(Context context, AttributeSet attrs) {
super(context, attrs);

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout);

mPicRatio = typedArray.getFloat(R.styleable.RatioLayout_picRatio, 0);

mRelative = typedArray.getInt(R.styleable.RatioLayout_relative, RELATIVE_WIDTH);

typedArray.recycle();
}

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

// 获取控件宽度模式,若控件宽度固定,已知图片的宽高比,求控件的高度
int parentWidthMode = MeasureSpec.getMode(widthMeasureSpec);

// 获取控件高度模式,若控件高度固定,已知图片的宽高比,求控件的宽度
int parentHeightMode = MeasureSpec.getMode(heightMeasureSpec);

if (parentWidthMode == MeasureSpec.EXACTLY && mPicRatio != 0 && mRelative == RELATIVE_WIDTH) {// 控件宽度固定,已知图片的宽高比,求控件的高度
// 得到父容器的宽度
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
// 得到孩子的宽度
int childWidth = parentWidth - getPaddingLeft() - getPaddingRight();
// 控件的宽度/控件的高度 = mPicRatio;

// 计算孩子的高度
int childHeight = (int) (childWidth / mPicRatio + .5f);

// 计算父容器的高度
int parentHeight = childHeight + getPaddingBottom() + getPaddingTop();

// 主动测绘孩子.固定孩子的大小
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
measureChildren(childWidthMeasureSpec, childHeightMeasureSpec);

// 设置自己的测试结果
setMeasuredDimension(parentWidth, parentHeight);

} else if (parentHeightMode == MeasureSpec.EXACTLY && mPicRatio != 0 && mRelative == RELATIVE_HEIGHT) {
// 控件高度固定,已知图片的宽高比,求控件的宽度
// 得到父亲的高度
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);

// 得到孩子的高度
int childHeight = parentHeight - getPaddingBottom() - getPaddingTop();

// 控件的宽度/控件的高度 = mPicRatio;
// 计算控件宽度
int childWidth = (int) (childHeight * mPicRatio + .5f);

// 得到父亲的宽度
int parentWidth = childWidth + getPaddingRight() + getPaddingLeft();

// 主动测绘孩子.固定孩子的大小
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
measureChildren(childWidthMeasureSpec, childHeightMeasureSpec);

// 设置自己的测试结果
setMeasuredDimension(parentWidth, parentHeight);

} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

}
}
这个布局的使用跟FrameLayout差不多,只要嵌入一个显示图片(只放一个)的ImageView并设置宽高比,它就会按图片比例进行显示了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: