view变化监听器ViewTreeObserver介绍

A view tree observer is used to register listeners that canbe notified of global changes in the view tree. Such global eventsinclude, but are not limited to, layout of the whole tree,beginning of the drawing pass, touch mode change.... AViewTreeObserver should never be instantiated by applications as itis provided by the views hierarchy. Refer toView.getViewTreeObserver() for moreinformation.

从上面的描述中,不难看出,ViewTreeObserver是用来帮助我们监听某些View的某些变化的。

在 ViewTreeObserver 中,包含了以下几个接口:

interfaceViewTreeObserver.OnGlobalFocusChangeListener

interfaceViewTreeObserver.OnGlobalLayoutListener

interface ViewTreeObserver.OnPreDrawListener

interfaceViewTreeObserver.OnScrollChangedListener

interfaceViewTreeObserver.OnTouchModeChangeListener

本文将测试除 ViewTreeObserver.OnScrollChangedListener外的四个接口

1.    创建一个 Android Project ,修改 main.xml 使之如下:

[html] view plaincopy

  1. <? xml version = "1.0" encoding = "utf-8" ?>
  2. < LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
  3. android:id = "@+id/full_screen"
  4. android:orientation= "vertical"
  5. android:layout_width= "fill_parent"
  6. android:layout_height= "fill_parent"
  7. >
  8. < TextView
  9. android:id = "@+id/tv_show"
  10. android:layout_width= "fill_parent"
  11. android:layout_height= "wrap_content"
  12. android:text = ""
  13. android:textSize = "32px"
  14. android:textColor = "#FFFF00"
  15. />
  16. < EditText
  17. android:id = "@+id/ed_enter1"
  18. android:layout_width= "fill_parent"
  19. android:layout_height= "wrap_content"
  20. android:text = ""
  21. />
  22. < EditText
  23. android:id = "@+id/ed_enter2"
  24. android:layout_width= "fill_parent"
  25. android:layout_height= "wrap_content"
  26. android:text = ""
  27. />
  28. < TextView
  29. android:id = "@+id/tv_display"
  30. android:layout_width= "fill_parent"
  31. android:layout_height= "wrap_content"
  32. android:text = ""
  33. />
  34. < Button
  35. android:id = "@+id/button"
  36. android:layout_width= "fill_parent"
  37. android:layout_height= "wrap_content"
  38. android:text = "OK"
  39. />
  40. </ LinearLayout >

注意:给 layout 增加一个 id : full_screen

2.    Activity 对应的 Java 代码如下:

[java] view plaincopy

  1. public class ControlViewTreeObserver extends Activity
  2. implements
  3. OnClickListener,
  4. ViewTreeObserver.OnTouchModeChangeListener,          // 用于监听 Touch 和非 Touch 模式的转换
  5. ViewTreeObserver.OnGlobalLayoutListener,                     // 用于监听布局之类的变化,比如某个空间消失了
  6. ViewTreeObserver.OnPreDrawListener,                              // 用于在屏幕上画 View 之前,要做什么额外的工作
  7. ViewTreeObserver.OnGlobalFocusChangeListener         // 用于监听焦点的变化
  8. {
  9. private TextView tv_show ;
  10. private ViewTreeObserver vto ;
  11. private View all ;
  12. private EditText ed1 ;
  13. private EditText ed2 ;
  14. private TextView tv_display ;
  15. private Button button ;
  16. private boolean btnClicked ;
  17. @Override
  18. public void onCreate(Bundle savedInstanceState)
  19. {
  20. super .onCreate(savedInstanceState);
  21. setContentView(R.layout. main );
  22. tv_show = (TextView) this .findViewById(R.id. tv_show );
  23. all = this .findViewById(R.id. full_screen );                                 // 得到整个屏幕对象 , 因为顶层 layout 的 width 和 height 都是 fill_parent
  24. vto = (ViewTreeObserver) all .getViewTreeObserver();         // 通过 getViewTreeObserver 获得 ViewTreeObserver 对象
  25. tv_display = (TextView) this .findViewById(R.id. tv_display );
  26. ed1 = (EditText) this .findViewById(R.id. ed_enter1 );
  27. ed2 = (EditText) this .findViewById(R.id. ed_enter2 );
  28. button = (Button) this .findViewById(R.id. button );
  29. button .setOnClickListener( this );
  30. vto .addOnTouchModeChangeListener( this );                         // 增加对应的 Listener
  31. vto .addOnGlobalFocusChangeListener(this );                       // 增加对应的 Listener
  32. vto .addOnPreDrawListener( this );                                              // 增加对应的 Listener
  33. vto .addOnGlobalLayoutListener( this );                                     // 增加对应的 Listener
  34. }
  35. // onTouchModeChanged 是接口 ViewTreeObserver.OnTouchModeChangeListener
  36. // 中定义的方法。
  37. @Override
  38. public void onTouchModeChanged( boolean isInTouchMode)
  39. {
  40. if (isInTouchMode) tv_show .setText( "In touch mode" );
  41. else tv_show .setText( "Not in touch mode" );
  42. }
  43. // onGlobalLayout 是接口 ViewTreeObserver.OnGlobalLayoutListener
  44. // 中定义的方法。
  45. // Callback method to be invokedwhen the global layout state or the
  46. // visibility of views within the view treechanges
  47. @Override
  48. public void onGlobalLayout()
  49. {
  50. if ( btnClicked )
  51. {
  52. if (! ed2 .isShown())
  53. ed1 .setText( " 第二个 EditText 不见了 " );
  54. else
  55. ed1 .setText( " 第二个 EditText 出来了 " );
  56. }
  57. }
  58. // onPreDraw 是接口 ViewTreeObserver.OnPreDrawListener
  59. // 中定义的方法。
  60. @Override
  61. public boolean onPreDraw()
  62. {
  63. // 在屏幕上画出 ed1 控件之间 , 给它增加一个提示 , 并改变其字体大小
  64. ed1 .setHint( " 在 onPreDraw 方法中增加一个提示信息 " );
  65. ed1 .setTextSize(( float ) 20.0);
  66. //return false;   // Return true to proceed with the current drawing pass, or falseto cancel.
  67. return true ;       // 如果此处不返回 true , 则整个界面不能完整显示。
  68. }
  69. // onGlobalFocusChanged 是接口 ViewTreeObserver.OnGlobalFocusChangeListener
  70. // 中定义的方法。
  71. // 焦点发生变化时,会触发这个方法的执行
  72. @Override
  73. public void onGlobalFocusChanged(View oldFocus, ViewnewFocus)
  74. {
  75. if (oldFocus != null && newFocus!= null )
  76. {
  77. tv_display .setText( "Focus /nFROM:/t" + oldFocus.toString() + "/n    TO:/t" + newFocus.toString());
  78. }
  79. }
  80. @Override
  81. public void onClick(View v)
  82. {
  83. // 改变 ed2 的可见性 , 会触发 onGlobalLayout 方法的执行
  84. btnClicked = true ;
  85. if (v.getId() == R.id. button )
  86. {
  87. if ( ed2 .isShown())
  88. ed2 .setVisibility(View. INVISIBLE );
  89. else
  90. ed2 .setVisibility(View. VISIBLE );
  91. }
  92. }
  93. }

3.    运行结果:

可以看到第一个 EditText 中存在字体发生了变化的提示信息,这种效果是在 onPreDraw() 方法中实现的。

用鼠标点击屏幕上的第二个 EditText ,

有两个变化:

一个是有 Not in touch mode 变成了 In touch mode ,二是显示了焦点变化方面的信息。它们分别是 onTouchModeChanged 和 onGlobalFocusChanged 这两个方法所输出的信息。

如果用模拟器右边的键盘进行操作,将交掉移动到第一个 EditText ,则又会回到 Not in touch mode 的状态。

点击 OK 按钮,改变第二个 EditText 的可见性:

第一个 EditText 中的内容是在 onGlobalLayout 方法中设定的。

view变化监听器ViewTreeObserver介绍

时间: 2024-11-05 08:39:40

view变化监听器ViewTreeObserver介绍的相关文章

ViewPager的简单用法+适配器+监听器的介绍

之前的actionbar+fragment文章中写过viewpager的简单用法,但因为是融合的文章,所以今天把viewpager提取出来写了.方便查询浏览~ 思路: 1.在布局文件中设置viewpager控件 2.在acitvity中找到它 3.自定义一个适配器,这个适配器需要一个list<View>来构造 4.定义一个list<View>来放入几个view,并用其来初始化适配器 5.给viewPager来设置适配器和监听器 实现: 1.布局文件,这里放一个指示文字.实际中可以用

Swift - iOS中各种视图控制器(View Controller)的介绍

在iOS中,不同的视图控制器负责不同的功能,采用不同的风格向用户呈现信息.下面对各个视图控制器做个总结: 1,标准视图控制器 - View Controller 这个控制器只是用来呈现内容.通常会用来作为子类,以向屏幕中添加逻辑. 2,导航控制器 - Navigation Controller 这个控制器呈现一个视图控制器的栈,应用程序可以在上面推入更多的视图控制器. 当新视图推入栈,或旧视图弹出栈时,导航控制器会以动画的形式(比如卷动)显示隐藏这些视图. 使用样例:系统“设置”应用程序 3,表

Cocos2d-x场景变化相关功能介绍

现场由导演级交换机Director实现.之间的相关的功能,如下面: runWithScene(Scene* scene).该函数能够执行场景.仅仅能在启动第一个场景时候调用该函数.假设已经有一个场景执行情况下则不能调用该函数. replaceScene(Scene* scene). 切换到下一个场景. 用一个新的场景替换当前场景.当前场景被终端释放. pushScene(Scene* scene).切换到下一个场景.将当前场景挂起放入到场景堆栈中,然后再切换到下一个场景中. void popSc

Java中的过滤器,拦截器,监听器---------简单易懂的介绍

过滤器: 过滤器其主要特点在于:取你需要的东西,忽视那些不需要的东西!在程序中,你希望选择中篇文章中的所有数字,你就可以针对性的挑选数字! 拦截器: 拦截器其主要特点在于:针对你不要的东西进行拦截,比如说,在一个BBS里面你希望人家不要留“小乌鸦”的这个词,那你就可能采用拦截器! 监听器: 是一个事件处理过程,这个过程的取舍,可以让你的代码成为过滤器,还是成为拦截器~~~比如,你想监听一段用户的数据中有没有1有的话就打印111!这就需要程序都监听用户输入的东西了!if(***..equls('1

自定义的TextView,使部分内容拥有点击事件,并在点击内容上方出现对应的词义等信息

直接看效果图: 上面图中是一个TextView,注册部分内容(KeyWord)是其拥有点击事件,并通过计算KeyWord的坐标,显示KeyWord的想要的一些信息 /** * 一个TextView中包含一个可以点击的KeyWord(关键词),并通过点击关键词,在对应关键词位置正上方展示关键词对应的解释等逻辑 * @author DuGuang * */ public class MainActivity extends Activity { private KeyWordTextView mTv

图形的初级变化使用View

图形的初级变化使用View view就是一个试图,而viewController就是这些试图的一个容器--试图控制器.以下内容是view的一小部分关联,主要是按钮的使用,试图的变化.在Main.storyboard里面添加控件,如下图 试图上的button分别是: switch按钮.我们常见的一种按钮,有打开喝关闭两种状态. 灰色区域--一个view添加背景色为灰色,目的是让读者看见将要变化的一段区域. Action按钮.使view变化颜色. Stop按钮.使变化颜色和转动暂停. rotatio

RecyclerView详细介绍&amp;使用。

<主菜>RecyclerView 简介 RecyclerView是Android 5.0提供的新控件,已经用了很长时间了,但是一直没有时间去仔细的梳理一下.现在有时间了,决定来整理下. 官方文档中是这样介绍的: A flexible view for providing a limited window into a large data set. RecyclerView比listview更先进更灵活,对于很多的视图它就是一个容器,可以有效的重用和滚动.当数据动态变化的时候请使用它. 专业术

ANDROID_MARS学习笔记_S01_002View、监听器初步

一.View.监听器介绍 二.在Activity中获取view和设置属性,设置button的监听器 1.activity_main.xml 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_par

java利用WatchService实时监控某个目录下的文件变化并按行解析(注:附源代码)

首先说下需求:通过ftp上传约定格式的文件到服务器指定目录下,应用程序能实时监控该目录下文件变化,如果上传的文件格式符合要求,将将按照每一行读取解析再写入到数据库,解析完之后再将文件改名. 一. 一开始的思路 设置一个定时任务,每隔一分钟读取下指定目录下的文件变化,如果有满足格式的文件,就进行解析. 这种方式很繁琐,而且效率低,效率都消耗在了遍历.保存状态.对比状态上了! 而且无法利用OS的很多功能. 二. WatchService介绍 1. 该类的对象就是操作系统原生的文件系统监控器!我们都知