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代码此处此处下载!(随后上传!)

时间: 2024-10-12 23:05:25

Android从零单排之获取ImageView的宽高为0?的相关文章

Android从零单排之自动跟新

Android从零单排之自动跟新 转载请注明出处:http://blog.csdn.net/crazy1235/article/details/45584621 自动更新原理 当我们发布我们的应用程序的时候,肯定会想到后续版本的更新,那么该怎么对我们的程序进行更新呢? 更新APK的原理实际上就是比较程序中的AndroidManifest.xml中的versionCode进行对比,如果发现更高版本的code,则代表有新版本的程序发布,此时就可以对用户提示"请更新新版本". 友盟自动更新介

android获取控件宽高和屏幕宽高

一.获取屏幕宽高 1.android界面简单介绍 要获取屏幕宽高,我们可以先从android的界面构成了解 android的界面主要由三部分构成:1.状态栏 2.标题栏 3.内容区域 \ (1)状态栏 状态栏主要用来显示一些系统图标,应用的通知图标和系统时间. (2)标题栏 android中标题栏主要用来显示当前位置,3.0过后添加了ActionBar,拥有了导航和OptionMenu的功能,5.0又新添加了ToolBar控件,和ActionBar类似,但自定义的空间更充足 (3)内容区域 an

动态获取手机屏幕宽高及动态设置控件宽高

1.获取手机屏幕宽高: DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int screenWidth = dm.widthPixels; int screenHeight = dm.heightPixels; 22.根据屏幕宽度为控件设置动态设置宽高: imageView.setImageResource(R.drawable.newscar); L

Adatper中获取宽高为0的问题

但是我们想在getView()中获取ImageView的宽和高存在问题,在getView()里面刚开始显示item的时候利用ImageView.getWidth() 获取的都是0,为什么刚开始获取不到宽和高呢,因为我们使用LayoutInflater来将XML布局文件Inflater()成View的时候,View并没有显示在界面上面,表明并没有对View进行onMeasure(), onLayout(), onDraw()等操作,必须等到retrue convertView的时候,表示该item

动态设置ImageView的宽高以及位置

如何动态设置ImageView的宽高以及位置 package com.pic; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; public class PicTest extends Activity { private final

当Bitmap的宽度大于ImageView的最大显示宽度时对ImageView的宽高重新计算来适应Bitmap的宽高(转)

当bitmap的宽大于ImageView显示控件的宽度时,如果不对ImageView的宽高重新计算,那么Imageview的高度就会超过显示图片的高度,用户体验将会很差,所以我们需要重新计算显示控件的宽高,这里我们假定ImageView的最大宽度为屏幕的宽度.利用下面这个工具类就可以很好解决问题了: Android获取屏幕宽度和高度:// WindowManager manage=getWindowManager();// Display display=manage.getDefaultDis

在渲染前获取 View 的宽高

在渲染前获取 View 的宽高 这是一个比较有意义的问题,或者说有难度的问题,问题的背景为:有时候我们需要在view渲染前去获取其宽高,典型的情形是,我们想在onCreate.onStart.onResume中去获取view的宽高.如果大家尝试过,会发现,这个时候view还没有measure好,宽高都为0,那到底该怎么做才能正确获取其宽高呢,下面给出三种方法(还有其他方法, 比如监听器回调等): Activity/View#onWindowFocusChanged :这个方法表明,view已经初

根据图片的链接获取图片的宽高

//根据图片的链接获取图片的宽高 - (CGSize)downloadImageSizeWithURL:(id)imageURL { NSURL *URL = nil; if([imageURL isKindOfClass:[NSURL class]]){ URL = imageURL; } if([imageURL isKindOfClass:[NSString class]]){ URL = [NSURL URLWithString:imageURL]; } if(URL == nil) r

js获取隐藏元素宽高的方法

网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了. 例如: <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>test</title> </head> <bo