很多同行在开发中可能会遇到这样的问题,就是在加载图片的时候会出现图片变形的问题.其实这很可能就是你的图片宽高比和图片所在容器的宽高比不匹配造成的.比如说图片的宽为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

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">
<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>

加载的过程中图片变形了? --教你自定义自动适配图片宽高比的RatioLayout的更多相关文章

  1. 动态加载JS过程中如何判断JS加载完成

    在正常的加载过程中,js文件的加载是同步的,也就是说在js加载的过程中,浏览器会阻塞接下来的内容的解析.这时候,动态加载便显得尤为重要了,由于它是异步加载,因此,它可以在后台自动下载,并不会妨碍其它内 ...

  2. 加载dll过程中assembly失败

    错误现象: 进行插件读取时出现错误:“尝试从一个网络位置加载程序集,在早期版本的 .NET Framework 中,这会导致对该程序集进行沙盒处理.此发行版的 .NET Framework 默认情况下 ...

  3. Sqoop import加载HBase过程中,遇到Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x

    在执行hbase sqoop抽取的时候,遇到了一个错误,如下图: 在执行程序的过程中,遇到权限问题很正常,也容易让人防不胜防,有问题就想办法解决,这个是关键. 解决办法如下: 第一步:su hdfs, ...

  4. openlayers加载天地图过程中遇到跨域问题

    // 采用openlayers加载天地图 var layer = new ol.layer.Tile({ source: new ol.source.XYZ({ // crossOrigin: 'An ...

  5. log4j的学习和log4j在程序中使用的加载作用过程

    昨天进行代码评审的时候,大家都纠结在了日志信息应该如何输出上,其实我想大家应该一直都在使用log4j来对日志信息进行输出,但是未想应该有很大一部分人对log4j是不了解的,我遇到这个问题的时候也到网上 ...

  6. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  7. 把图片加载到BufferedImage中

    把图片加载到BufferedImage 中有什么作用呢?它就可以利用 ImageIO.write(image, "JPEG", response.getOutputStream() ...

  8. 利用“反射”动态加载R文件中的资源

    前几天做一个Android下面数据库相关的应用.用ListVIew展示表中数据的时候我希望能给表中每一条记录,加一个展示的图片.但是用数据库保存图片是比较难搞的.于是就把所需图片都保存到res下的dr ...

  9. 创建控制器的方法、控制器加载view过程、控制器view的生命周期、多控制器组合

    在介绍四大对象的那篇博客中,可以基本了解到程序启动的过程: main-->UIApplicationMain-->创建UIApplication的实例和app代理AppDelegate的实 ...

随机推荐

  1. Unity : Ran out of trampolines of type 2

    Unity 导出游戏到 iOS 平台,当时选择的设置是 mono2x, 结果游戏各种莫名其妙的崩溃,再崩溃, 几乎运行不到一分钟就崩溃,而在 editor 和 android 平台都是正常的. 查看出 ...

  2. arduino 入手

    新买了个ardhuino 入门套件 1. Win7 Driver issue: Need to install the below drivers, because my windows is ins ...

  3. 百度音乐api

    百度音乐全接口 会利用使用接口找歌简单又快捷 http://tingapi.ting.baidu.com/v1/restserver/ting 获取方式:GET 参数:format=json或xml& ...

  4. java-代理模式及动态代理

    代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在考虑到性能或安全等因素的情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. ...

  5. 练习ajax的时候出现这个问题 还没解决

    VM601:1 Uncaught SyntaxError: Unexpected end of JSON input  应该怎么办呢

  6. 解析html并使用canvas进行渲染

    在学习html5的时候,使用canvas实现了对html文本的解析和渲染,支持的tag有<p>.<i>.<b>.<u>.<ul>.<l ...

  7. 美帝的emal to message gateway

    Provider Email to SMS Address Format AllTel number@text.wireless.alltel.com AT&T number@txt.att. ...

  8. 重拾java之路之webservice

         Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性.你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web servi ...

  9. unity 状态机 + svn + 码云 上篇

    最近刚找到在实习,忙于公司一个c++ 项目 ,一直想写博客来着,没时间写今天熬夜打算先献上自己前几天自己封装的一个fsm状态机 话不多说,直接上正题,这篇博客主要是在学校的时候状态机一直使用的是pla ...

  10. 微信公共平台开发-(.net实现)2--ACCESSTOKEN值获得

    成功的走出第一步后,我们紧接着趁热打铁开始下一步: 成为了开发者之后微信平台会给您AppId和AppSecret,在订阅号中是没有的,所以因该申请一下服务号, 若没有请注意上一篇http://www. ...