自定义布局之宽高比布局的实现
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>
下面是具体的代码实现
首先声明两个属性,一个是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并设置宽高比,它就会按图片比例进行显示了
相关文章推荐
- Windows串口类
- 开源 java CMS - FreeCMS2.4 模型管理
- 《基于MFC的OpenGL编程》Part 6 Animation
- 51nod 1042:数字0-9的数量
- 不同文本模型的选择之ROC曲线
- Linux学习方法之以始为终—Linux工作分类
- sql server 2008误操作 恢复数据库的方法--日志尾部备份
- 2016.2.29 工作笔记
- 机房重构——存储过程详解
- 十个看似无用实则逆天的数据应用小段子
- 当宽字节遇到了搜索型注入还能注入么?
- LeetCode:Roman to Integer
- Android LogUtil(log工具类)
- 冒泡排序
- 市场需求调研-待续
- nginx upstream timed out 10060错误解决
- DialogFragment
- acm系统开发笔记
- Maven配置
- Android客户端性能优化(魅族资深工程师毫无保留奉献)