加载的过程中图片变形了? --教你自定义自动适配图片宽高比的RatioLayout
2016-11-22 10:14
309 查看
很多同行在开发中可能会遇到这样的问题,就是在加载图片的时候会出现图片变形的问题.其实这很可能就是你的图片宽高比和图片所在容器的宽高比不匹配造成的.比如说图片的宽为200,高为100.宽高比就是2,那么这时候把它放在宽高比为1或者3的控件上就会分别出现变窄和变宽的问题.只有在容器宽高比为2的时候图片才会和原始显示效果一样.怎样解决这个问题呢?这个时候就可以创建一个能够自适应图片宽高比的父容器来包裹ImageView就可以了.在使用RatioLayout的时候要注意以下几点:
1)ImageView的宽高属性都要改成match_parent
2)要指定RatioLayout以宽还是高来进行适配
3)在attrs.xml中添加控件的两个属性:一个是宽高比,一个是适配标准.前者为float,后者为enum类型,分别制定width=0和height=1
4)创建一个类RatioLayout继承FrameLayout,重写两个构造方法以及onMeasure方法
具体代码如下:
I.RatioLayout.java
II.attrs.xml
1)ImageView的宽高属性都要改成match_parent
2)要指定RatioLayout以宽还是高来进行适配
3)在attrs.xml中添加控件的两个属性:一个是宽高比,一个是适配标准.前者为float,后者为enum类型,分别制定width=0和height=1
4)创建一个类RatioLayout继承FrameLayout,重写两个构造方法以及onMeasure方法
具体代码如下:
I.RatioLayout.java
import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.widget.FrameLayout; import com.yangtao.googleplay.R;
/** * Created by 杨涛 on 2016/11/18. * 版权所有 翻版必究 * 自定义的容器控件 * 可以实现的功能如下: * 1.可以根据指定的宽高比和模式来让子控件动态适应屏幕 */
public class RatioLayout extends FrameLayout { private float mRatio; private static final int RATIOMODE_WIDTH = 0; private static final int RATIOMODE_HEIGHT = 1; private int ratioMode = RATIOMODE_WIDTH; public RatioLayout(Context context) { this(context, null); } public RatioLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout); mRatio = typedArray.getFloat(R.styleable.RatioLayout_ratio, 1); ratioMode = typedArray.getInt(R.styleable.RatioLayout_ratioMode, RATIOMODE_WIDTH); typedArray.recycle(); } public void setRatio(float ratio) { mRatio = ratio; } public void setRatioMode(int ratioMode) { this.ratioMode = ratioMode; } /* 根据固定的宽计算高 宽是已经确定的 高需要根据ratio来确定 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY && ratioMode == RATIOMODE_WIDTH) { int width = MeasureSpec.getSize(widthMeasureSpec); //拿到了控件的宽 int height = (int) ((width / mRatio) + .5f); setMeasuredDimension(width, height); setAndMeasureChilds(width, height); } else if (heightMode == MeasureSpec.EXACTLY && ratioMode == RATIOMODE_HEIGHT) { //如果高度已经确定的话 int height = MeasureSpec.getSize(heightMeasureSpec); //拿到了控件的宽 int width = (int) ((height * mRatio) + .5f); setMeasuredDimension(width, height); setAndMeasureChilds(width, height); } else { super.setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); } } /** * 得到子控件应有的宽和高,然后调用方法测量子控件的宽和高 * @param width * @param height */ private void setAndMeasureChilds(int width, int height) { int childWidth = width - getPaddingLeft() - getPaddingRight(); int childHeight = height - getPaddingTop() - getPaddingBottom(); int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY); int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY); measureChildren(childWidthMeasureSpec, childHeightMeasureSpec); } }
II.attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RatioLayout"> << 4000 span style="color:#800000;">attr name="ratio" format="float"></attr> <attr name="ratioMode" format="enum"> <enum name="width" value="0"></enum> <enum name="height" value="1"></enum> </attr> </declare-styleable> </resources>
相关文章推荐
- Android下WebView的图片适配加载与文字自动换行处理
- Symbian下自定义加载bmp图片详细过程
- 自动生成AJAX加载图片
- 自定义制作 自动定时更换图片的桌面背景 html页面
- JS防止变形自动调整图片尺寸
- 自定义Loading载入状态(含图标) 及解决Flex中GIF动画图片加载时显示动起来
- 图片预加载并且自动等比例缩放的JS插件[转]
- 自动重新加载-自定义ClassLoader初步
- JQuery 可自定义自动播放图片 文字 也可以带按钮点击特效
- Flex :自定义Loading载入状态(含图标) 及解决Flex中GIF动画图片加载时显示动起来
- 自动判断页面上的图片是否加载成功,不成功替换为默认图片
- souapp:图片加载loading自动生成
- ACAD在自动加载自定义菜单后,批量打印程序出故障。
- js 加载时自动调整图片大小
- js 加载时自动调整图片大小
- JS 自动识别上传图片的宽高并且可以联动修改(联动效果,不变形)
- 自定义制作 自动定时更换图片的桌面背景 html页面
- 图片加载时自动显示等比例缩略图
- 阻止Image控件中的图片自动加载。
- jquery图片预加载+自动等比例缩放插件