ViewTreeObserver类(这类有意思)

本文深入解析ViewTreeObserver类的功能,包括其内部接口、公共方法及使用示例,详细阐述了如何注册监听视图树中的焦点状态变化、全局布局更改、预绘制通知、滚动事件及触摸模式改变,以及如何通过回调函数响应这些全局事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

ViewTreeObserver:视图树监听类。

ViewTreeObserver类不能被应用程序实例化,因为它是由视图提供的,使用的话,可以调用视图的getViewTreeObserver()方法返回实例。

详细的说呢,这个类是一个注册监听视图树的观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。

1、内部类    

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

2、公共方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**注册一个回调函数,当在一个视图树中的焦点状态发生改变时调用这个回调函数。
  * 参数 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)<span style= "font-size:14px;font-family:Microsoft YaHei;" > </span>

3、使用示例

在这段代码中,XML文件定义了一个简单的相对布局,通过使用ViewTreeObserver的内部类OnPreDrawListener,当这个视图将要绘制的时候,回调onPreDraw()方法,在这个方法里,简单的获取了该相对布局的实际可用宽高(因为还有其它布局,所以实际尺寸小于屏幕像素大小)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 定义一个布局
private RelativeLayout mLayout;
 
private float mMaxWidth; // 图片最大宽度
private float mMaxHeight; // 图片最大高度
private boolean isMeasured = false ; // 是否已经计算大小
 
// 获取在XML文件中的该布局
mLayout = (RelativeLayout) findViewById(R.id.mlayout);
 
// 获取RelativeLayout的高度和宽度,该尺寸表示了图片显示的最大宽高
ViewTreeObserver vto = mLayout.getViewTreeObserver();
 
// 内部类-当一个视图树将要绘制时,所要调用的回调函数的接口类
vto.addOnPreDrawListener( new OnPreDrawListener() {
     @Override
     public boolean onPreDraw() {
         if (isMeasured == false ) {
             mMaxWidth = mLayout.getMeasuredWidth();
             mMaxHeight = mLayout.getMeasuredHeight();
             isMeasured = true ;
             // 其它代码
             // ...
         }
         return true ;
     }
});

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值