这个博客注册很久了,可是一直都没有勇气来写一点东西。今天解决了一个让我纠结很久的问题,于是,我决定开始我的博客生涯,希望我能坚持下去。
不知道是不是只有我遇到了这个问题,在ListView中显示图片,当需求是显示的图片宽度最宽,但是高度自适应时。在xml里设ImageView的高度属性是不能解决问题的。网上我也找了下方法。有说设 Android:adjustViewBounds这个属性的,它需要设maxheight和maxwidth配合使用,我开始加入的时候,在一些手机上也确实是成功,可是换了个手机之后,发现在不行。也就是说,在android版本这么多,厂商这么多的情况下。它不能保证效果是可以实现。然后也有方法说在设完图片图片之后,去根据图片的宽高比,设控件的高度,我没有去做代码的实现,因为我知道它可行,但是不是我想的要。
直接先上代码吧:
1 import android.content.Context; 2 import android.graphics.drawable.Drawable; 3 import android.util.AttributeSet; 4 import android.widget.ImageView; 5 import android.widget.RelativeLayout; 6 7 public class AutoHeightImageView extends ImageView { 8 9 private Drawable mDrawable = null; 10 private static int mWidth = 0; 11 12 public AutoHeightImageView(Context context, AttributeSet attrs) { 13 super(context, attrs); 14 } 15 16 public AutoHeightImageView(Context context) { 17 super(context); 18 } 19 20 public AutoHeightImageView(Context context, AttributeSet attrs, int defStyle) { 21 super(context, attrs, defStyle); 22 } 23 24 @Override 25 public void setImageDrawable(Drawable drawable) { 26 super.setImageDrawable(drawable); 27 mDrawable = getDrawable(); 28 if (mWidth != 0) { 29 setAutoHeight(); 30 } 31 } 32 33 @Override 34 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 35 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 36 if (mWidth == 0) { 37 mWidth = getMeasuredWidth(); 38 if (mDrawable != null) { 39 setAutoHeight(); 40 } 41 } 42 } 43 44 private void setAutoHeight() { 45 float scale = mDrawable.getMinimumHeight() / (float) mDrawable.getMinimumWidth(); 46 float height = mWidth * scale; 47 setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, (int) height)); 48 } 49 }
看完其实是很简单的东西,实现也就是根据图片的宽高比来完成,只是我把这些让到的控件的自定义里实现。说说需要注意的问题吧:在重写的OnMeasure()方法里,要在调用了super的方法之后,再能得到你在xml里ImageView的宽度,因为我这里高度由宽度决定,所以只能取最初那一次的,OnMeasure()方法会多次调用(没有去追究原因),这样,放到ListView里的时间,高度就能自适应了。
弄出来,自己是挺开心的,希望大家有意见和建议多多指出。也希望我能有更的东西分享出来,让大家帮忙优化,一起提高!
续:自己在复用这个控件的时候,发现在个问题,也又弄清楚了一个问题:
关于这名话的
setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, (int) height));
当我要这个控件用到一个LinearLayout下的时候,异常了,原来这个LayoutParams和它所在父控件有关。不分统一用一个,后改成了
if (getParent() instanceof RelativeLayout) { setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, (int) height)); } if (getParent() instanceof LinearLayout) { setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) height)); }
自己根据需要加吧!