一:问题说明
1.一般而言美工或者服务器给的图片大小不一定一直的,但是一般变屏幕所展示的大,并且会出现占用的位置很奇怪的现象;
2.也就是说:但给了大小不一致但是宽高比一致的时候的ImageView适配问题;
二.解决方案:
1.在ImageView外面套一层FragmentLayout,通过父类改写子类的缩放问题l;
布局如下:
<org.itheima56.googleplay.widget.RatioLayout
xmlns:itheima="http://schemas.android.com/apk/res/org.itheima56.googleplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
itheima:ratio="2.43"
itheima:relative="width" >
<!-- 通过宽高比和宽度值来确定 高度 -->
<ImageView
android:id="@+id/item_subject_iv_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_default" />
</org.itheima56.googleplay.widget.RatioLayout> 2.资源文件attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RatioLayout">
<attr name="ratio" format="float" />
<attr name="relative">
<enum name="width" value="0" />
<enum name="height" value="1" />
</attr>
</declare-styleable>
</resources> 3.对ImageView的外层的FragmentLayout进行复写:
该FragmentLayout的作用是根据设置的宽高比,和缩放对象 :一般来说看ImageView的width和height那个是match_parent觉得的
public class RatioLayout extends FrameLayout
{
public static final int RELEATIVE_WIDTH = 0;
public static final int RELEATIVE_HEIGHT = 1;
private float mRatio;
private int mReleative = RELEATIVE_WIDTH; // 相对宽或是高来计算
public RatioLayout(Context context) {
this(context, null);
}
public RatioLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RatioLayout);
mRatio = ta.getFloat(R.styleable.RatioLayout_ratio, 0);
mReleative = ta.getInt(R.styleable.RatioLayout_relative, RELEATIVE_WIDTH);
ta.recycle();
}
public void setRatio(float ratio)
{
this.mRatio = ratio;
}
public void setReleative(int releative)
{
this.mReleative = releative;
}
@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 && mRatio != 0 && mReleative == RELEATIVE_WIDTH)
{
// 通过宽高比和宽度值来确定 高度
int width = widthSize - getPaddingLeft() - getPaddingRight();
int height = (int) (width / mRatio + 0.5f);
// 给孩子设置宽高
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
measureChildren(childWidthMeasureSpec, childHeightMeasureSpec);
// 给自己设置宽度和高度
setMeasuredDimension(widthSize, height + getPaddingTop() + getPaddingBottom());
}
else if (heightMode == MeasureSpec.EXACTLY && mRatio != 0 && mReleative == RELEATIVE_HEIGHT)
{
// 通过高度计算宽度的值
// 已知 高度,宽高比,计算宽度的值
int height = heightSize - getPaddingTop() - getPaddingBottom();
int width = (int) (height * mRatio + 0.5f);
// 给孩子设置宽高
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
measureChildren(childWidthMeasureSpec, childHeightMeasureSpec);
// 给自己设置宽度和高度
setMeasuredDimension(width + getPaddingLeft() + getPaddingRight(), heightSize);
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
} 4.代码使用:
itheima:ratio="2.43"---->要么在xml布局中写上宽高比
itheima:relative="width"----->依赖width
或者在代码中使用