您的位置:首页 > 移动开发 > Android开发

Android 实现自定义宽高比的ImageView

2016-03-31 14:23 211 查看

前言

我们为什么要用到宽高比固定的ImageView呢?因为Android屏幕大小不一样,同样一张图片可能会在不同的设备上显示效果不同,会发生拉伸等情况。今天就来说一种解决方案,让图片的宽高比固定,保证不变形。为了实现这个效果,我们需要自定义一个ImageView。

思路

根据这个ImageView的宽度或者高度去设置,分以下几种情况:

1.宽度确定,高度不确定,通过宽度设置高度

2.高度确定,宽度不确定,通过高度设置宽度

3.宽高都确定,无需设置,因为设置没效果

4.宽高都不确定,无法设置宽高比

代码

我们先在styles.xml中自定义属性

<declare-styleable name="MyImageView">
<attr name="ratio" format="float"/>
</declare-styleable>


然后我们在自定义View中去获取这个属性:

public class MyImageView extends ImageView {
//宽高比,由我们自己设定
private float ratio;
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获得属性名称和对应的值
//        for (int i = 0; i < attrs.getAttributeCount() ; i++) {
//            String name = attrs.getAttributeName(i);
//            String value = attrs.getAttributeValue(i);
//            System.out.println("====name: "+name+"value:"+value);
//        }
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageView);
//根据属性名称获取对应的值,属性名称的格式为类名_属性名
ratio = typedArray.getFloat(R.styleable.MyImageView_ratio, 0.0f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取宽度的模式和尺寸
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
//获取高度的模式和尺寸
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//宽确定,高不确定
if(widthMode == MeasureSpec.EXACTLY&&heightMode!=MeasureSpec.EXACTLY&&ratio!=0){
heightSize = (int) (widthSize*ratio+0.5f);//根据宽度和比例计算高度
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
}else if(widthMode!=MeasureSpec.EXACTLY&&heightMode==MeasureSpec.EXACTLY&ratio!=0){
widthSize = (int) (heightSize/ratio+0.5f);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize,MeasureSpec.EXACTLY);
}else{
throw new RuntimeException("无法设定宽高比");
}
//必须调用下面的两个方法之一完成onMeasure方法的重写,否则会报错
//        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
}
/**
* 设置宽高比
* @param ratio
*/
public void setRatio(float ratio){
this.ratio = ratio;
}
}


最后我们在布局文件中使用这个自定义的ImageView

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:gravity="center"
tools:context="com.example.hecun.testone.MainActivity">
<com.example.hecun.testone.MyImageView
android:id="@+id/imageview"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:src="@drawable/ym1"
custom:ratio="1"
android:scaleType="fitXY"
/>
</LinearLayout>


我们在这里设置了宽高比为1,我们来看看效果:



顺便给出ratio为2和3时的效果图





最后,给出源码下载位置

点此下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: