获取屏幕、控件大小方法汇总

    |     2015年7月1日   |   Android UI界面   |     0 条评论   |    1582

在Android中,有时需要对控件进行测量,得到的控件宽度和高度,在OnCreate函数中通过控件对象调用getHeight方法获取到的仍然是0,Measure方法之后调用getMeasuredWidth的值还是0。

原因是因为当OnCreate函数发生时,只是提供了数据初始化的机会,此时还没有正式绘制图形。而绘制图形在OnDraw中进行,此时计算又显得太晚。容易想到的办法是:希望能在程序刚刚测量好某个指定控件后,拿到它的宽度和高度立刻进行计算或数据初始化。这就需要有一个方法来监听到这个事件的发生,幸好Android提供了这样的机制,利用View类中的getViewTreeObserver方法,可以获取到指定View的观察者,在绘制控件前的一刹那进行回调,这样速度上又不耽误,得到的数据由是准确的,但此方法在之后可能会被反复调用,因此需要加入限制,普通需求下,只计算一次就够了,代码如下:
一、获取控件尺寸

方法一:
View layout = findViewById(R.id.popwindow_btn);
ViewTreeObserver vto = layout.getViewTreeObserver();

    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
	public boolean onPreDraw() {
	   if (hasMeasured == false) {

		int btWidth = layout.getMeasuredWidth();
		int btHeight = layout.getMeasuredHeight();
		hasMeasured = true;

	  }
		return true;
	}
    });

方法二:
	ViewTreeObserver vto = mPopupBtn.getViewTreeObserver();
	vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

		@Override
		public void onGlobalLayout() {
	             if (hasMeasured == false) {
			int btWidth = mPopupBtn.getMeasuredWidth();
			int btHeight = mPopupBtn.getMeasuredHeight();
	                    hasMeasured = true;
		     }
	});

方法三:
将一个runnable添加到Layout队列中:View.post()

简单地说,只要用View.post()一个runnable就可以了。runnable对象中的方法会在View的measure、layout等事件后触发

UI事件队列会按顺序处理事件。在setContentView()被调用后,事件队列中会包含一个要求重新layout的message,所以任何你post到队列中的东西都会在Layout发生变化后执行。

1 final View view=//smth;
 ...
 view.post(new Runnable() {
             @Override
             public void run() {
                 view.getHeight(); //height is ready
             }
         });

这个方法比ViewTreeObserver好:
1、你的代码只会执行一次,而且你不用在在每次执行后将Observer禁用,省心多了。
2、语法很简单

二、获取状态栏尺寸

/**
	 * 状态栏高度
	 *
	 * @return
	 */
	public int getStatusBarHeight() {
		Rect frame = new Rect();
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		int statusBarHeight = frame.top;

		return statusBarHeight;
	}

三、获取标题栏尺寸

	/**
	 * 获取标题栏高度
	 *
	 * @return
	 */
	public int getTitleBarHeight() {
		int statusBarHeight = getStatusBarHeight();
		int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT)
				.getTop();
		// statusBarHeight是上面所求的状态栏的高度
		int titleBarHeight = contentTop - statusBarHeight;
		return titleBarHeight;
	}

	public int getTitleBarHeight(){
		return getActionBar().getHeight();
	}

四、获取手机屏幕尺寸

/**
	 * 获取手机屏幕尺寸 width,height
	 *
	 * @return
	 */
	public int[] getScreenSize() {
		DisplayMetrics dm = new DisplayMetrics();
		// 获取屏幕信息
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		int screenWidth = dm.widthPixels;
		int screenHeigh = dm.heightPixels;

		return new int[] { screenWidth, screenHeigh };
	}

五、获取内容区域尺寸

  int contentViewHeight = findViewById(android.R.id.content).getHeight(); // 屏幕内容区域高度

 

六、弹框实例

/**
	 * 显示弹出窗口
	 *
	 * @param buttonHeight
	 */
	public void showPopupWindow(int buttonHeight) {
		View contentView = getPopWindowContentViewBySimpleAdatper();

		//=============================计算弹框宽高=====================
		int margin = 50;// 弹窗边距

		int contentViewHeight = findViewById(android.R.id.content).getHeight(); // 屏幕内容区域高度

		int[] screenSize = getScreenSize();
		int screenWidth = screenSize[0];
		int screenHeigh = screenSize[1];

		int titleHeight = getTitleBarHeight();// getActionBar().getHeight();//
												// 获取Title高度,确保Title(ActionBar)没有隐藏
		int statusBarHeight = getStatusBarHeight();

		int popwindowWidth = screenWidth - 2 * margin;
		int popwindowHeight = contentViewHeight - buttonHeight - margin;
		// int popwindowHeight = screenHeigh - buttonHeight - titleHeight - statusBarHeight - margin;
		//====================================================

		mPopwindow = new PopupWindow(contentView, popwindowWidth,popwindowHeight);

		//-----------实现点击空白区域弹框消失--------------
		mPopwindow.setBackgroundDrawable(new BitmapDrawable());
		mPopwindow.setFocusable(true);
		mPopwindow.setOutsideTouchable(true);
		//-------------------------------------------

		mPopupBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mPopwindow.isShowing()) {
					mPopwindow.dismiss();
				} else {
//					mPopwindow.showAsDropDown(v, 10, -5);

					int[] location = new int[2];
			        v.getLocationOnScreen(location); //获取在整个屏幕内的绝对坐标  location [0]--->x坐标,location [1]--->y坐标

			        Logs.v("location[0] :"+location[0] + " location[1] :"+location[1]);

			        mPopwindow.showAtLocation(v, Gravity.NO_GRAVITY, location[0]+50, location[1]+v.getHeight());
				}
			}
		});

	}
转载请注明来源:获取屏幕、控件大小方法汇总
回复 取消