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.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
 2   //当在一个视图树中的焦点状态发生改变时,所要调用的回调函数的接口类
 3
 4   interface  ViewTreeObserver.OnGlobalLayoutListener
 5   //当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类
 6
 7   interface  ViewTreeObserver.OnPreDrawListener
 8   //当一个视图树将要绘制时,所要调用的回调函数的接口类
 9
10   interface  ViewTreeObserver.OnScrollChangedListener
11   //当一个视图树中的一些组件发生滚动时,所要调用的回调函数的接口类
12
13   interface  ViewTreeObserver.OnTouchModeChangeListener
14   //当一个视图树的触摸模式发生改变时,所要调用的回调函数的接口类

四、公共方法

 /**注册一个回调函数,当在一个视图树中的焦点状态发生改变时调用这个回调函数。
 2   * 参数 listener    将要被添加的回调函数
 3   *异常 IllegalStateException       如果isAlive() 返回false
 4   */
 5  public void addOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener listener)
 6
 7
 8  /**注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。
 9   *参数 listener    将要被添加的回调函数
10   *异常 IllegalStateException       如果isAlive() 返回false
11   */
12  public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)
13   
14
15   
16  /**注册一个回调函数,当一个视图树将要绘制时调用这个回调函数。
17   *参数 listener    将要被添加的回调函数
18   *异常 IllegalStateException       如果isAlive() 返回false
19   */
20  public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)
21
22  
23  /**注册一个回调函数,当一个视图发生滚动时调用这个回调函数。
24   *参数 listener    将要被添加的回调函数
25   *异常 IllegalStateException       如果isAlive() 返回false
26   */
27  public void addOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener listener)
28
29  
30  /**注册一个回调函数,当一个触摸模式发生改变时调用这个回调函数。
31   *参数 listener    将要被添加的回调函数
32   *异常 IllegalStateException       如果isAlive() 返回false
33   */
34  public void addOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener listener)
35
36   
37  //当整个布局发生改变时通知相应的注册监听器。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在GONE状态下,它可以被手动的调用
38  public final void dispatchOnGlobalLayout ()
39
40  /**当一个视图树将要绘制时通知相应的注册监听器。如果这个监听器返回true,则这个绘制将被取消并重新计划。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在一个GONE状态下,它可以被手动的调用
41   *返回值  当前绘制能够取消并重新计划则返回true,否则返回false。
42   */
43  public final boolean dispatchOnPreDraw ()
44
45  /**指示当前的ViewTreeObserver是否可用(alive)。当observer不可用时,任何方法的调用(除了这个方法)都将抛出一个异常。如果一个应用程序保持和ViewTreeObserver一个历时较长的引用,它应该总是需要在调用别的方法之前去检测这个方法的返回值。
46   *返回值 但这个对象可用则返回true,否则返回false
47   */
48  public boolean isAlive ()
49
50
51  /**移除之前已经注册的全局布局回调函数。
52   *参数 victim 将要被移除的回调函数
53   *异常 IllegalStateException       如果isAlive() 返回false
54   */
55  public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
56   
57  /**移除之前已经注册的焦点改变回调函数。
58   *参数 victim 将要被移除的回调函数
59   *异常 IllegalStateException       如果isAlive() 返回false
60   */
61  public void removeOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener victim)
62   
63  /**移除之前已经注册的预绘制回调函数。
64   *参数 victim 将要被移除的回调函数
65   *异常 IllegalStateException       如果isAlive() 返回false
66   */
67  public void removeOnPreDrawListener (ViewTreeObserver.OnPreDrawListener victim)
68   
69  /**移除之前已经注册的滚动改变回调函数。
70   *参数 victim 将要被移除的回调函数
71   *异常 IllegalStateException       如果isAlive() 返回false
72   */
73  public void removeOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener victim)
74  
75  /**移除之前已经注册的触摸模式改变回调函数
76   *参数 victim 将要被移除的回调函数
77   *异常  IllegalStateException       如果isAlive() 返回false
78   */
79  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);

转自http://www.tuicool.com/articles/fi6BJ3N和http://www.cnblogs.com/xingfuzzhd/archive/2013/06/25/3154674.html

 
时间: 2024-10-20 02:07:09

android笔记:获取View组件宽度以及ViewTreeObserver的相关文章

获取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

Android笔记:获取url或uri字符串中的参数值

d Uri.parse(mArgUrl).getQueryParameter("id") Android笔记:获取url或uri字符串中的参数值

Android自定View组件方法

一.开发自定义View组件 View组件只是一个矩形的空白区域,并没有任何内容.对于Android应用的其他UI组件来说,它们都继承于View组件,然后在View组件提供的空白区域上绘制外观.当Android系统提供的UI组件不足以满足项目需要时,我们可以通过继承View来派生一个自定义组件. 举一个实例:实现一个跟随手指的小球.当用户通过手指在屏幕上拖动时,程序监听到这个手机动作,并把手指动作的位置传入自定义UI组件,并通知该组件重绘即可.开发步骤如下: 1.实现一个继承于View的子类 pa

通过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

Android笔记自定义View之制作表盘界面

前言 最近我跟自定义View杠上了,甚至说有点上瘾到走火入魔了.身为菜鸟的我自然要查阅大量的资料,学习大神们的代码,这不,前两天正好在郭神在微信公众号里推送一片自定义控件的文章--一步步实现精美的钟表界面.正适合我这种菜鸟来学习,闲着没事,我就差不多依葫芦画瓢也写了一个自定义表盘View,现在纯粹最为笔记记录下来.先展示下效果图: 下面进入正题 自定义表盘属性 老规矩,先在attrs文件里添加表盘自定义属性 <declare-styleable name="WatchView"&

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

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

Android 获取View宽度

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

打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)

前言 最近在做项目时,使用了一个开源的下拉刷新ListView组件,极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(ListView.GridView等)通用的下拉刷新.上拉自动加载的组件.但是这种通过修改Margin的形式感觉不是特别的流畅,因此在这漫长的国庆长假又花了点时间用另外的原理实现了一遍,特此分享出来. 基本原理 原理就是自定义一个ViewGroup,将Header View, Content View,

【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 组件构造方法 构造方