获取View组件宽度以及ViewTreeObserver

View宽高测量方法:

测量方法有三种,如下:

1)(直接在onCreate()执行)

int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
imageView.measure(w, h);
int height =imageView.getMeasuredHeight();
int width =imageView.getMeasuredWidth();
textView.append("\n"+height+","+width);

2)2和3都是在onCreate()调用完后回调拿到组件的宽高

ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    public boolean onPreDraw() {
        int height = imageView.getMeasuredHeight();
        int width = imageView.getMeasuredWidth();
        textView.append("\n"+height+","+width);
        return true;
    }
});

3)

ViewTreeObserver vto2 = imageView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());
    }
});

注意:方法一比其他方法多一次onMeasure计算,方法二的回调函数会被多次调用。

转自http://blog.csdn.net/johnny901114/article/details/7839512

ViewTreeObserver

一、结构

public final class ViewTreeObserver extends Object
    java.lang.Object
         android.view.ViewTreeObserver

二、概述

这是一个注册监听视图树的观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。ViewTreeObserver不能够被应用程序实例化,因为它是由视图提供,参照getViewTreeObserver()以查看更多信息。

三、内部类

interface  ViewTreeObserver.OnGlobalFocusChangeListener
//当在一个视图树中的焦点状态发生改变时,所要调用的回调函数的接口类

interface  ViewTreeObserver.OnGlobalLayoutListener
//当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类

interface  ViewTreeObserver.OnPreDrawListener
//当一个视图树将要绘制时,所要调用的回调函数的接口类

interface  ViewTreeObserver.OnScrollChangedListener
//当一个视图树中的一些组件发生滚动时,所要调用的回调函数的接口类

interface  ViewTreeObserver.OnTouchModeChangeListener
//当一个视图树的触摸模式发生改变时,所要调用的回调函数的接口类

四、公共方法

/**注册一个回调函数,当在一个视图树中的焦点状态发生改变时调用这个回调函数。
 * 参数 listener    将要被添加的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener listener)

/**注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。
 *参数 listener    将要被添加的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)
  

  
/**注册一个回调函数,当一个视图树将要绘制时调用这个回调函数。
 *参数 listener    将要被添加的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
 public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)

 
/**注册一个回调函数,当一个视图发生滚动时调用这个回调函数。
  *参数 listener    将要被添加的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener listener)  

 
/**注册一个回调函数,当一个触摸模式发生改变时调用这个回调函数。
  *参数 listener    将要被添加的回调函数
  *异常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener listener)

  
//当整个布局发生改变时通知相应的注册监听器。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在GONE状态下,它可以被手动的调用
public final void dispatchOnGlobalLayout ()

/**当一个视图树将要绘制时通知相应的注册监听器。如果这个监听器返回true,则这个绘制将被取消并重新计划。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在一个GONE状态下,它可以被手动的调用
 *返回值  当前绘制能够取消并重新计划则返回true,否则返回false。
*/
public final boolean dispatchOnPreDraw ()

/**指示当前的ViewTreeObserver是否可用(alive)。当observer不可用时,任何方法的调用(除了这个方法)都将抛出一个异常。如果一个应用程序保持和ViewTreeObserver一个历时较长的引用,它应该总是需要在调用别的方法之前去检测这个方法的返回值。
 *返回值 但这个对象可用则返回true,否则返回false
*/
public boolean isAlive ()

/**移除之前已经注册的全局布局回调函数。
  *参数 victim 将要被移除的回调函数
  *异常 IllegalStateException       如果isAlive() 返回false
*/
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
  
/**移除之前已经注册的焦点改变回调函数。
 *参数 victim 将要被移除的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
public void removeOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener victim)
  
/**移除之前已经注册的预绘制回调函数。
 *参数 victim 将要被移除的回调函数
  *异常 IllegalStateException       如果isAlive() 返回false
*/
public void removeOnPreDrawListener (ViewTreeObserver.OnPreDrawListener victim)
  
/**移除之前已经注册的滚动改变回调函数。
 *参数 victim 将要被移除的回调函数
 *异常 IllegalStateException       如果isAlive() 返回false
*/
public void removeOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener victim)
 
/**移除之前已经注册的触摸模式改变回调函数
 *参数 victim 将要被移除的回调函数
 *异常  IllegalStateException       如果isAlive() 返回false
*/
public void removeOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener victim)

五、代码示例


1、创建监听器

private final ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      int width = -1;
      int height = -1;

      try {
        width = getActivity().getWindow().getDecorView().getWidth();
        height = getActivity().getWindow().getDecorView().getHeight();
      } catch (Exception e) {
        // called too early. so, just skip.
      }

      if (width != -1 && mGlobalLayoutWidth != width) {//只有当尺寸真正有了数值,即已经确定了,更新UI才有意义
        mGlobalLayoutWidth = width;
        updateUI();
      } else if (height != -1 && mGlobalLayoutHeight != height) {
        mGlobalLayoutHeight = height;
    updateUI();
 } } };

2、一般在onCreate或onCreateView中注册监听器

mViewTreeObserver = getActivity().getWindow().getDecorView().getViewTreeObserver();
mViewTreeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);

原文地址:https://www.cnblogs.com/ganchuanpu/p/8452698.html

时间: 2024-10-16 07:42:07

获取View组件宽度以及ViewTreeObserver的相关文章

android笔记:获取View组件宽度以及ViewTreeObserver

View宽高测量方法: 测量方法有三种,如下: 1)(直接在onCreate()执行) int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); imageView.measure(w, h); int height =imageView.getMeasured

通过MeasuerSpec获取View的宽度和高度

在onCreate中无法通过getHeight方法获取View的宽高.我们可以通过MeasureSpec实现. int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); textView.measure(w, h); int width =textView.ge

HackThirteen 在onCreate()方法中获取View的宽度和高度

1.概要: Android源代码中很多模块都使用了post()方法,深入理解框架曾运行机制对于避开类似于本例中的小陷阱是很重要的 2.问题提出: 如果开发一些依赖于UI控件的宽和高的功能,开发者可能会用到View的getHeight()和getWidth()方法.试图在Activity的 onCreate()方法中获取控件的宽和高.遗憾的是如果开发者在onCreate()方法中调用上述方法,会发现返回值都是0. 3.解释问题原因: 当onCreate()方法被调用时,会通过LayoutInfla

Activity中获取view的高度和宽度为0的原因以及解决方案

在activity中可以调用View.getWidth.View.getHeight().View.getMeasuredWidth() .View.getgetMeasuredHeight()来获得某个view的宽度或高度,但是在onCreate().onStrart().onResume()方法中会返回0,这是应为当前activity所代表的界面还没显示出来没有添加到WindowPhone的DecorView上或要获取的view没有被添加到DecorView上或者该View的visibili

Android 获取View宽度

/***************************************************************************** * Android 获取View宽度 * 说明: * 在View默认的构造函数里无法获取到View的宽高,需要采用另外的方式获取. * * 2016-6-15 深圳 南山平山村 曽剑锋 ****************************************************************************/

[Flex] 动态获取组件宽度和高度

flex中我们有时并不想一开始就设置某个组件的宽度和高度,而想动态获取某个组件经填充后的width和height,但是会发现width和height均为0,这时我们可以注册一下两个事件之一来解决. 1 import mx.events.FlexEvent; 2 import mx.events.ResizeEvent; 3 //video为组件VideoPlayer的实例 4 video.addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateCo

Android获取view高度

getMeasuredHeight()与getHeight的区别 实际上在当屏幕可以包裹内容的时候,他们的值相等, 只有当view超出屏幕后,才能看出他们的区别: getMeasuredHeight()是实际View的大小,与屏幕无关, 而getHeight的大小此时则是屏幕的大小. 当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的大小 具体方法 我们知道在oncreate中View.getWidth和View.getHeight无法获得一个v

【Android 应用开发】 自定义 View 组件 -- 圆形进度条

转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487 代码下载 : -- CSDN 下载地址 : http://download.csdn.net/detail/han1202012/8069497 ; -- GitHub 地址 : https://github.com/han1202012/CircleProcess.git ; -- 工程示例 : 一. 相关知识点解析 1. 自定义 View 组件构造方法 构造方

react native 中View组件中的ref属性是什么

在用Reactnative写工程时,默认奇妙的有一种像OC中,或者Java 中或者当前类的私有属性的想法,state 和props都不能满足时,就是ref   它能达到其他语言中持有一个view组件,并且局部的刷新 ref 接受值为string类型的参数或者一个函数function callback.这一特性让开发者对ref的使用更加灵活. render() { return <TextInput ref={(c) => this._input = c} />; }, component