有时候图片的宽高比例不对的话,图片显示的就很别扭,那么怎么才能让图片按照正常的比例显示而且宽度还能matchparent呢? 这就要自定义一个能够自适应的父布局,这样imageView即可以正常显示了,(之所以不在IamgeView上面进行修改是因为逻辑可能会复杂一点,所以自定义了一个父布局)
首先自定义一个RadioLayout继承FrameLayout,然后重写onMeasure()方法中,重新按照宽高比例进行测量
package zz.itcast.googleplay09.view; import android.content.Context; import android.util.AttributeSet; import android.widget.FrameLayout; /** * 等比例的父控件 * @author fanday * */ public class RatioLayout extends FrameLayout { //图片的宽高比例 private float ratio = 2.43f; public void setRatio(float ratio) { this.ratio = ratio; } public RatioLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initAttrs(attrs); } /** * 初始化属性 */ private void initAttrs(AttributeSet attrs) { //namespace:命名控件,attribute:属性名称,defaultValue:默认值 float ratioValue = attrs.getAttributeFloatValue("http://schemas.android.com/apk/res/zz.itcast.googleplay09", "ratio", 2.43f); setRatio(ratioValue); } public RatioLayout(Context context, AttributeSet attrs) { super(context, attrs); initAttrs(attrs); } public RatioLayout(Context context) { super(context); } /** * 确定测量标准 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //RatioLayout的宽度测量标准:widthMeasureSpec ,mode+size //获取RatioLayout的宽度大小 int widthSize = MeasureSpec.getSize(widthMeasureSpec); //获取RatioLayout的宽度模式 int widthMode = MeasureSpec.getMode(widthMeasureSpec); //图片宽高比例2.43 int picWidthSize = 0; int picHeightSize = 0; //如果图片的高度确定 //RatioLayout的高度测量标准:heightMeasureSpec int heigthSize = MeasureSpec.getSize(heightMeasureSpec); int heigthMode= MeasureSpec.getMode(heightMeasureSpec); //如果宽度是精确值 if(widthMode == MeasureSpec.EXACTLY&&heigthMode != MeasureSpec.EXACTLY){ //计算图片的高度 picWidthSize = widthSize - getPaddingLeft() - getPaddingRight(); picHeightSize = (int) (picWidthSize/ratio); } <pre name="code" class="java"> //如果高度是精确值matchParent的model就是EXACTLY WrapContent的model是ATMOST if(heigthMode == MeasureSpec.EXACTLY&&widthMode != MeasureSpec.EXACTLY){ picHeightSize = heigthSize - getPaddingBottom() - getPaddingTop(); picWidthSize = (int) (picHeightSize*ratio); } //RatioLayout新测量标准 int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(picWidthSize+getPaddingLeft()+getPaddingRight(), MeasureSpec.EXACTLY); int newHeigthMeasureSpec = MeasureSpec.makeMeasureSpec(picHeightSize+getPaddingTop()+getPaddingBottom(), MeasureSpec.EXACTLY); //把计算好的宽高直接给super.onMeasure()调用 super.onMeasure(newWidthMeasureSpec, newHeigthMeasureSpec); } }
上面的这个自定义View用到了自定义属性,下面就来说下自定义属性怎么实现,再res下values目录下建立attrs xml文件
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- declare-styleable name是当前控件名 --> <declare-styleable name="zz.itcast.googleplay09.view.RatioLayout"> <!-- attr name 属性名 format 当前属性的数据类型 --> <attr name="ratio" format="float"/> </declare-styleable> </resources><declare-styleable name="zz.itcast.googleplay09.view.RatioLayout"> name指定为自定义view类的全路径,然后在布局的xml中就可以使用自定义的属性了
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:itcast="http://schemas.android.com/apk/res/zz.itcast.googleplay09" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="9dip" android:layout_marginRight="9dip" android:background="@drawable/list_item_bg" > <zz.itcast.googleplay09.view.RatioLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/ratiolayout" itcast:ratio = "2.43" android:padding="5dp" > <ImageView android:id="@+id/item_icon" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitCenter" android:src="@drawable/ic_default" /> </zz.itcast.googleplay09.view.RatioLayout>xmlns:itcast="http://schemas.android.com/apk/res/zz.itcast.googleplay09"需要我们自定义一个命名空间
这样ImageView就可以实现宽高缩放功能了