博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
view变化监听器ViewTreeObserver介绍
阅读量:6426 次
发布时间:2019-06-23

本文共 5249 字,大约阅读时间需要 17 分钟。

 

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]
  1. <? xml version = "1.0" encoding = "utf-8" ?>  
  2.   
  3. LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"  
  4.   
  5. android:id = "@+id/full_screen"  
  6.   
  7.    android:orientation= "vertical"  
  8.   
  9.    android:layout_width= "fill_parent"  
  10.   
  11.    android:layout_height= "fill_parent"  
  12.   
  13. >    
  14.   
  15.      
  16.   
  17.    TextView  
  18.   
  19.                   android:id = "@+id/tv_show"  
  20.   
  21.            android:layout_width= "fill_parent"  
  22.   
  23.            android:layout_height= "wrap_content"  
  24.   
  25.            android:text = ""  
  26.   
  27.            android:textSize = "32px"  
  28.   
  29.            android:textColor = "#FFFF00"  
  30.   
  31.    />  
  32.   
  33.      
  34.   
  35.    EditText  
  36.   
  37.    android:id = "@+id/ed_enter1"  
  38.   
  39.    android:layout_width= "fill_parent"  
  40.   
  41.            android:layout_height= "wrap_content"  
  42.   
  43.            android:text = ""  
  44.   
  45.         />  
  46.   
  47.           
  48.   
  49.    EditText  
  50.   
  51.    android:id = "@+id/ed_enter2"  
  52.   
  53.    android:layout_width= "fill_parent"  
  54.   
  55.            android:layout_height= "wrap_content"  
  56.   
  57.            android:text = ""  
  58.   
  59.         />  
  60.   
  61.           
  62.   
  63.         TextView  
  64.   
  65.                   android:id = "@+id/tv_display"  
  66.   
  67.            android:layout_width= "fill_parent"  
  68.   
  69.            android:layout_height= "wrap_content"  
  70.   
  71.            android:text = ""  
  72.   
  73.    />  
  74.   
  75.      
  76.   
  77.         Button  
  78.   
  79.                   android:id = "@+id/button"  
  80.   
  81.            android:layout_width= "fill_parent"  
  82.   
  83.            android:layout_height= "wrap_content"  
  84.   
  85.            android:text = "OK"  
  86.   
  87.    />      
  88.   
  89. </ LinearLayout >  

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

 

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

[java]
  1. public class ControlViewTreeObserver extends Activity  
  2.   
  3. implements  
  4.   
  5. OnClickListener,  
  6.   
  7. ViewTreeObserver.OnTouchModeChangeListener,          // 用于监听 Touch 和非 Touch 模式的转换  
  8.   
  9. ViewTreeObserver.OnGlobalLayoutListener,                     // 用于监听布局之类的变化,比如某个空间消失了  
  10.   
  11. ViewTreeObserver.OnPreDrawListener,                              // 用于在屏幕上画 View 之前,要做什么额外的工作  
  12.   
  13. ViewTreeObserver.OnGlobalFocusChangeListener         // 用于监听焦点的变化  
  14.   
  15. {  
  16.   
  17.         private TextView tv_show ;  
  18.   
  19.    private ViewTreeObserver vto ;  
  20.   
  21.    private View all ;  
  22.   
  23.      
  24.   
  25.    private EditText ed1 ;  
  26.   
  27.    private EditText ed2 ;     
  28.   
  29.    private TextView tv_display ;  
  30.   
  31.    private Button button ;  
  32.   
  33.    private boolean btnClicked ;  
  34.   
  35.      
  36.   
  37.    @Override  
  38.   
  39.    public void onCreate(Bundle savedInstanceState)  
  40.   
  41.    {  
  42.   
  43.        super .onCreate(savedInstanceState);  
  44.   
  45.        setContentView(R.layout. main );  
  46.   
  47.          
  48.   
  49.        tv_show = (TextView) this .findViewById(R.id. tv_show );  
  50.   
  51.        all = this .findViewById(R.id. full_screen );                                 // 得到整个屏幕对象 , 因为顶层 layout 的 width 和 height 都是 fill_parent  
  52.   
  53.        vto = (ViewTreeObserver) all .getViewTreeObserver();         // 通过 getViewTreeObserver 获得 ViewTreeObserver 对象  
  54.   
  55.          
  56.   
  57.        tv_display = (TextView) this .findViewById(R.id. tv_display );  
  58.   
  59.        ed1 = (EditText) this .findViewById(R.id. ed_enter1 );  
  60.   
  61.        ed2 = (EditText) this .findViewById(R.id. ed_enter2 );  
  62.   
  63.        button = (Button) this .findViewById(R.id. button );  
  64.   
  65.        button .setOnClickListener( this );  
  66.   
  67.          
  68.   
  69.        vto .addOnTouchModeChangeListener( this );                         // 增加对应的 Listener  
  70.   
  71.        vto .addOnGlobalFocusChangeListener(this );                       // 增加对应的 Listener  
  72.   
  73.        vto .addOnPreDrawListener( this );                                              // 增加对应的 Listener  
  74.   
  75.        vto .addOnGlobalLayoutListener( this );                                     // 增加对应的 Listener  
  76.   
  77.    }  
  78.   
  79.    
  80.   
  81.    // onTouchModeChanged 是接口 ViewTreeObserver.OnTouchModeChangeListener  
  82.   
  83.    // 中定义的方法。  
  84.   
  85.         @Override  
  86.   
  87.         public void onTouchModeChanged( boolean isInTouchMode)  
  88.   
  89.         {  
  90.   
  91.                   if (isInTouchMode) tv_show .setText( "In touch mode" );  
  92.   
  93.                   else tv_show .setText( "Not in touch mode" );  
  94.   
  95.         }  
  96.   
  97.    
  98.   
  99.         // onGlobalLayout 是接口 ViewTreeObserver.OnGlobalLayoutListener  
  100.   
  101.         // 中定义的方法。  
  102.   
  103.         // Callback method to be invokedwhen the global layout state or the  
  104.   
  105.         // visibility of views within the view treechanges  
  106.   
  107.         @Override  
  108.   
  109.         public void onGlobalLayout()  
  110.   
  111.         {  
  112.   
  113.                   if ( btnClicked )  
  114.   
  115.                   {  
  116.   
  117.                            if (! ed2 .isShown())  
  118.   
  119.                                     ed1 .setText( " 第二个 EditText 不见了 " );  
  120.   
  121.                            else  
  122.   
  123.                                     ed1 .setText( " 第二个 EditText 出来了 " );  
  124.   
  125.                   }  
  126.   
  127.         }  
  128.   
  129.    
  130.   
  131.         // onPreDraw 是接口 ViewTreeObserver.OnPreDrawListener  
  132.   
  133.        // 中定义的方法。  
  134.   
  135.         @Override  
  136.   
  137.         public boolean onPreDraw()  
  138.   
  139.         {  
  140.   
  141.                   // 在屏幕上画出 ed1 控件之间 , 给它增加一个提示 , 并改变其字体大小  
  142.   
  143.                   ed1 .setHint( " 在 onPreDraw 方法中增加一个提示信息 " );  
  144.   
  145.                   ed1 .setTextSize(( float ) 20.0);  
  146.   
  147.                     
  148.   
  149.                   //return false;   // Return true to proceed with the current drawing pass, or falseto cancel.  
  150.   
  151.                   return true ;       // 如果此处不返回 true , 则整个界面不能完整显示。  
  152.   
  153.         }                                              
  154.   
  155.    
  156.   
  157.         // onGlobalFocusChanged 是接口 ViewTreeObserver.OnGlobalFocusChangeListener  
  158.   
  159.         // 中定义的方法。  
  160.   
  161.         // 焦点发生变化时,会触发这个方法的执行  
  162.   
  163.         @Override  
  164.   
  165.         public void onGlobalFocusChanged(View oldFocus, ViewnewFocus)  
  166.   
  167.         {  
  168.   
  169.                   if (oldFocus != null && newFocus!= null )  
  170.   
  171.                   {  
  172.   
  173.                            tv_display .setText( "Focus /nFROM:/t" + oldFocus.toString() + "/n    TO:/t" + newFocus.toString());  
  174.   
  175.                   }  
  176.   
  177.         }  
  178.   
  179.    
  180.   
  181.         @Override  
  182.   
  183.         public void onClick(View v)  
  184.   
  185.         {  
  186.   
  187.                   // 改变 ed2 的可见性 , 会触发 onGlobalLayout 方法的执行  
  188.   
  189.                   btnClicked = true ;  
  190.   
  191.                   if (v.getId() == R.id. button )  
  192.   
  193.                   {  
  194.   
  195.                            if ( ed2 .isShown())  
  196.   
  197.                                     ed2 .setVisibility(View. INVISIBLE );  
  198.   
  199.                            else  
  200.   
  201.                                     ed2 .setVisibility(View. VISIBLE );  
  202.   
  203.                   }  
  204.   
  205.         }  
  206.   
  207. }  
 

3.    运行结果:

 

 

 

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

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

 

 

 

有两个变化:

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

 

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

 

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

 

 

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

转载地址:http://dfyga.baihongyu.com/

你可能感兴趣的文章
git使用教程2-更新github上代码
查看>>
张掖百公里,再次折戟
查看>>
SAP QM Batch to Batch的转移过账事务中的Vendor Batch
查看>>
本期最新 9 篇论文,帮你完美解决「读什么」的问题 | PaperDaily #19
查看>>
图解SSIS监视文件夹并自动导入数据
查看>>
Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)
查看>>
MyBatis Review——开发Dao的方法
查看>>
技术研发国产化进程加快 看传感器企业如何展示十八般武艺
查看>>
技术助力第三次革命
查看>>
《HTML与CSS入门经典(第8版)》——2.6 总结
查看>>
新手指南:在 Ubuntu 和 Fedora 上安装软件包
查看>>
在 CentOS7.0 上搭建 Chroot 的 Bind DNS 服务器
查看>>
大型网站的 HTTPS 实践(二):HTTPS 对性能的影响
查看>>
《Swift 权威指南》——第6章,第6.10节嵌套函数
查看>>
《自己动手做交互系统》——1.3 本章小结
查看>>
Mobile devices bundled with malware?
查看>>
《JavaScript面向对象精要》——1.5 访问属性
查看>>
《Python数据可视化编程实战》—— 第 1 章 准备工作环境
查看>>
Android应用性能优化最佳实践.1.1 Android Studio的优势
查看>>
《设计模式解析(第2版•修订版)》—第2章 2.2节什么是UML
查看>>