Android从零单排之获取ImageView的宽高为0?
问题描述
说起来我也够菜的!⊙﹏⊙b汗。
今天搞了一个关于图片的demo,想动态的改变一张图片的大小和margin值。但是在activity中获取imageview的宽度和高度的时候,总是0。哎,我tm就是搞不懂了,怎么能是0呢?
<span style="white-space:pre"> </span>imageView1 = (ImageView) findViewById(R.id.id_img1); int width = imageView1.getWidth(); int height = imageView1.getHeight();
分析原因
起初怀疑是我代码写的有问题,可能写错了,可是反复检查和实验了几次,还TM是0。蛋疼!后来上网一查,发现了新大陆了。
在onCreate方法中,控件其实还没有画好,也就是说当onCreate方法执行完了之后,才开始绘制控件,所以在onCreate方法中获取width和height返回的值是0。但是我又想onResume方法是不是可以呢?后来发现还是不行!我自定义了ImageView,然后打印量log日志,发现果然是这样,onCreate和onResume方法执行完了之后,才开始执行控件的测量(onMeasure)和绘制(onDraw)方法。
MyImageView.java---自定义ImageView类:
public class MyImageView extends ImageView { public MyImageView(Context context) { super(context); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i("imageview", "onMeasure..."); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.i("imageview", "onDraw..."); } }activity类:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo3); Log.i("imageview", "onCreate....."); } @Override protected void onResume() { super.onResume(); Log.i("imageview", "onResume....."); }打印出来的LOG日志如下:
解决办法
既然onCreate方法中不行,应该有其他的方法了!于是从网上找到了如下几种方法!
第一种方法:使用BitmapFactory。
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.songjiang); Log.i("imageview", "width: " + bitmap.getWidth()); Log.i("imageview", "height: " + bitmap.getHeight());
第二种方法: 使用MeasureSpec.makeMeasureSpec方法。
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); img.measure(w, h); Log.i("imageview2", "width: " + img.getMeasuredWidth()); Log.i("imageview2", "height: " + img.getMeasuredHeight());第三种方法:使用ViewTreeObserver.addOnPreDrawListener方法。
ViewTreeObserver vto = img.getViewTreeObserver(); vto.addOnPreDrawListener(new OnPreDrawListener() { @Override public boolean onPreDraw() { int height = img.getMeasuredHeight(); int width = img.getMeasuredWidth(); Log.i("imageview3", "width: " + width); Log.i("imageview3", "height: " + height); return true; } });
第四种方法:使用ViewTreeObserver.addOnGlobalLayoutListener方法。
ViewTreeObserver vto = img.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { img.getViewTreeObserver().removeGlobalOnLayoutListener(this); Log.i("imageview4", "width: " + img.getWidth()); Log.i("imageview4", "height: " + img.getHeight()); } });
注意:方法三会调用3次。
在代码中动态改变ImageView的宽高就很简单了!
DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int desityDpi = metrics.densityDpi; Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hi); int width = bitmap.getWidth() * 160 / desityDpi; int height = bitmap.getHeight() * 160 / desityDpi; LayoutParams params = imageView1.getLayoutParams(); params.width = width; params.height = height; imageView1.setLayoutParams(params);
下载
demo代码此处此处下载!(随后上传!)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。