AndroidGUI13:ViewTreeObserver的常用技巧

Android中图像变换Matrix的原理、代码验证和应用(二) 第二部分 代码验证 在第一部分中讲到的各种图像变换的验证代码如下,一共列出了10种情况。如果要验证其中的某一种情况,只需将相应的代码反注释即可。试验中用到的图片: 其尺寸为162 x 251。   每种变换的结果,请见代码之后的说明。 package com.pat.testtransformmatrix; import android.app.Activity; import 阅读详情

A view tree observer is used to register listeners that can be notified of global changes in the view tree. Such global events include, but are not limited to, layout of the whole tree, beginning of the drawing pass, touch mode change.... A ViewTreeObserver should never be instantiated by applications as it is provided by the views hierarchy. Refer to View.getViewTreeObserver() for more information.

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

 

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

interface ViewTreeObserver.OnGlobalFocusChangeListener

interface ViewTreeObserver.OnGlobalLayoutListener

interface ViewTreeObserver.OnPreDrawListener

interface ViewTreeObserver.OnScrollChangedListener

interface ViewTreeObserver.OnTouchModeChangeListener

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

 

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

<? xml version = "1.0" encoding = "utf-8" ?>

< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"

android:id = "@+id/full_screen"

    android:orientation = "vertical"

    android:layout_width = "fill_parent"

    android:layout_height = "fill_parent"

>  

   

    < TextView

                   android:id = "@+id/tv_show"

             android:layout_width = "fill_parent"

             android:layout_height = "wrap_content"

             android:text = ""

             android:textSize = "32px"

             android:textColor = "#FFFF00"

    />

   

    < EditText

    android:id = "@+id/ed_enter1"

    android:layout_width = "fill_parent"

             android:layout_height = "wrap_content"

             android:text = ""

         />

        

    < EditText

    android:id = "@+id/ed_enter2"

    android:layout_width = "fill_parent"

             android:layout_height = "wrap_content"

             android:text = ""

         />

        

         < TextView

                   android:id = "@+id/tv_display"

             android:layout_width = "fill_parent"

             android:layout_height = "wrap_content"

             android:text = ""

    />

   

         < Button

                   android:id = "@+id/button"

             android:layout_width = "fill_parent"

             android:layout_height = "wrap_content"

             android:text = "OK"

    />    

</ LinearLayout >

 

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

 

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

public class ControlViewTreeObserver extends Activity

implements

OnClickListener,

ViewTreeObserver.OnTouchModeChangeListener,            // 用于监听 Touch 和非 Touch 模式的转换

ViewTreeObserver.OnGlobalLayoutListener,                       // 用于监听布局之类的变化,比如某个空间消失了

ViewTreeObserver.OnPreDrawListener,                               // 用于在屏幕上画 View 之前,要做什么额外的工作

ViewTreeObserver.OnGlobalFocusChangeListener          // 用于监听焦点的变化

{

         private TextView tv_show ;

    private ViewTreeObserver vto ;

    private View all ;

   

    private EditText ed1 ;

    private EditText ed2 ;   

    private TextView tv_display ;

    private Button button ;

    private boolean btnClicked ;

   

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super .onCreate(savedInstanceState);

        setContentView(R.layout. main );

       

        tv_show = (TextView) this .findViewById(R.id. tv_show );

        all = this .findViewById(R.id. full_screen );                                  // 得到整个屏幕对象 , 因为顶层 layout 的 width 和 height 都是 fill_parent

        vto = (ViewTreeObserver) all .getViewTreeObserver();           // 通过 getViewTreeObserver 获得 ViewTreeObserver 对象

       

        tv_display = (TextView) this .findViewById(R.id. tv_display );

        ed1 = (EditText) this .findViewById(R.id. ed_enter1 );

        ed2 = (EditText) this .findViewById(R.id. ed_enter2 );

        button = (Button) this .findViewById(R.id. button );

        button .setOnClickListener( this );

       

        vto .addOnTouchModeChangeListener( this );                          // 增加对应的 Listener

        vto .addOnGlobalFocusChangeListener( this );                        // 增加对应的 Listener

        vto .addOnPreDrawListener( this );                                               // 增加对应的 Listener

        vto .addOnGlobalLayoutListener( this );                                      // 增加对应的 Listener

    }

 

    // onTouchModeChanged 是接口 ViewTreeObserver.OnTouchModeChangeListener

    // 中定义的方法。

         @Override

         public void onTouchModeChanged( boolean isInTouchMode)

         {

                   if (isInTouchMode) tv_show .setText( "In touch mode" );

                   else tv_show .setText( "Not in touch mode" );

         }

 

         // onGlobalLayout 是接口 ViewTreeObserver.OnGlobalLayoutListener

         // 中定义的方法。

         // Callback method to be invoked when the global layout state or the

         // visibility of views within the view tree changes

         @Override

         public void onGlobalLayout()

         {

                   if ( btnClicked )

                   {

                            if (! ed2 .isShown())

                                     ed1 .setText( " 第二个 EditText 不见了 " );

                            else

                                     ed1 .setText( " 第二个 EditText 出来了 " );

                   }

         }

 

         // onPreDraw 是接口 ViewTreeObserver.OnPreDrawListener

        // 中定义的方法。

         @Override

         public boolean onPreDraw()

         {

                   // 在屏幕上画出 ed1 控件之间 , 给它增加一个提示 , 并改变其字体大小

                   ed1 .setHint( " 在 onPreDraw 方法中增加一个提示信息 " );

                   ed1 .setTextSize(( float ) 20.0);

                  

                   //return false;    // Return true to proceed with the current drawing pass, or false to cancel.

                   return true ;        // 如果此处不返回 true , 则整个界面不能完整显示。

         }                                            

 

         // onGlobalFocusChanged 是接口 ViewTreeObserver.OnGlobalFocusChangeListener

         // 中定义的方法。

         // 焦点发生变化时,会触发这个方法的执行

         @Override

         public void onGlobalFocusChanged(View oldFocus, View newFocus)

         {

                   if (oldFocus != null && newFocus != null )

                   {

                            tv_display .setText( "Focus /nFROM:/t" + oldFocus.toString() + "/n     TO:/t" + newFocus.toString());

                   }

         }

 

         @Override

         public void onClick(View v)

         {

                   // 改变 ed2 的可见性 , 会触发 onGlobalLayout 方法的执行

                   btnClicked = true ;

                   if (v.getId() == R.id. button )

                   {

                            if ( ed2 .isShown())

                                     ed2 .setVisibility(View. INVISIBLE );

                            else

                                     ed2 .setVisibility(View. VISIBLE );

                   }

         }

}

 

3.     运行结果:

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

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


有两个变化:

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

 

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

 

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


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

 

AndroidGUI28:在onCreate方法中两次调用setContentView 在做Android开发的时候,有时候需要在一个Activity的里面调用两次setContentView方法。比如在应用启动的时候,开始显示欢迎界面,在显示欢迎界面的同时,进行后台数据的处理,等到后台数据准备好了,才显示真正的应用界面。这样的做法不会让使用者有突兀的感觉。反之,应 阅读详情

相关推荐

深入解析璞致PZ-ZU47DR RFSoC核心板:硬件架构与多通道ADC/DAC设计实战

本文深入解析璞致PZ-ZU47DR RFSoC核心板的硬件架构与多通道ADC/DAC设计实战。作为Xilinx Zynq UltraScale+ RFSoC系列的代表产品,PZ-ZU47DR集成了8通道5GSPS ADC和8通道9.85GSPS DAC,支持直接射频采样,大幅简化射频链路设计。文章详细介绍了其技术优势、设计挑战及实战技巧,为5G小基站、毫米波等应用场景提供高效解决方案。

meat5的博客 831

android ViewTreeObserver详细讲解

一、结构public final class ViewTreeObserver extends Objectjava.lang.Object android.view.ViewTreeObserver  二、概述    用于注册监听的视图树观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。ViewTreeObserv...

mmdev 288

Win11如何更改用户文件夹名(完整流程- 已验证可行)

把C盘所有文件备份,如果不想备份,则选择创建一个C盘的系统还原点(能在后续把C盘玩崩之后恢复原状)

Y_Aryan的博客 5万+

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

李光正的专栏 3万+

【ESP32-S3量产指南】基于Flash下载工具实现Release模式Flash加密与安全配置

本文详细介绍了ESP32-S3量产阶段如何通过Flash下载工具实现Release模式下的Flash加密与安全配置。从加密模式选择、工具配置到分区表优化,提供了一套完整的量产安全解决方案,帮助开发者有效防止固件泄露和篡改,确保设备安全。

weixin_28730131的博客 230

FPGA中Verilog HDL/VHDL实现NCO(数字控制振荡器)的查表法优化与性能分析

本文深入探讨了在FPGA中使用Verilog HDL/VHDL实现数字控制振荡器(NCO)的查表法优化与性能分析。文章详细解析了NCO的核心工作原理,包括相位累加器、查找表(ROM)的设计,并重点介绍了利用波形对称性压缩ROM、相位抖动注入等关键优化技巧,以提升无杂散动态范围(SFDR)并平衡速度、精度与资源消耗。

vscode6remote的博客 454

Android开发笔记之遇到的那些坑

在这篇文章中,将记录在Android开发过程中遇到的坑:以后的坑都将记录在这篇文章中…第一坑:视图树测量控件宽高在使用addOnPreDrawListener测量控件宽高时imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public

浮生的博客 4866

SAP物料分类账(ML)避坑指南:激活顺序错了怎么办?从CKMSTART到差异分摊的完整流程

本文详细解析SAP物料分类账(ML)的正确激活顺序与配置流程,帮助用户避免常见陷阱如'LKW无科目'、'在制品重估失败'等问题。从CKMSTART到差异分摊的完整流程,涵盖关键配置节点、典型报错分析与应急处理方案,确保产品成本控制(CO-PC)模块的顺利运行。

weixin_42524708的博客 258

Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

转载请包含网址:http://blog.youkuaiyun.com/pathuang68/article/details/7351317 一、Surface Surface就是“表面”的意思。在SDK的文档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”,翻译成中文就

玄机逸士的专栏 4万+

STM32CubeMX之DAC产成正弦波

“在之前的文章中曾经介绍过用TIM产生PWM做DAC用,STM32定时器输出PWM做DAC。部分型号的STM32单片机内部有专用的DAC,本篇文章将介绍如何用内部DAC+DMA产生正弦波...

zhang062061的专栏 1513

【PostgreSQL】PostgreSQL数据库函数比对模板(PG通用)

LOOKUP 函数从单行或单列区域 (区域:工作表上的两个或多个单元格。区域中的单元格可以相邻或不相邻。)或数组 (数组:用于建立可生成多个结果或可对在行和列中排列的一组参数进行运算的单个公式。数组区域共用一个公式;数组常量是用作参数的一组常量。LOOKUP 函数具有两种语法形式:向量形式和数组形式。vlookup查找匹配值超过255个字符显示#Value的解决办法。如果值为错误值 #N/A,则返回 TRUE。

tttzzzqqq2018的博客 1493

Pinyin4j的基本用法

1.     简单介绍 有时候,需要将汉字编程对应的拼音,以方便数据的处理。比如在Android手机应用的开发上,要查询联系人的姓名,通常都是用拼音进行查询的。比如要查询“曹孟德”,就可以输入“cmd”,即“曹孟德”三个汉字的拼音“caomengde”各字的首字母。但是怎样才能

玄机逸士的专栏 4万+

麒麟操作系统安装教程(保姆级)

本文介绍了如何在VM中安装麒麟操作系统,文章详细的介绍了麒麟操作系统按钻过步骤。

啊渊的专栏 1万+

Android中图像变换Matrix的原理、代码验证和应用(一)

第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类。Android中的Matrix是一个3 x 3的矩阵,其内容如下:   Matrix的对图像的处理可分为四类基本变换: Translate           平移变换 Rotate                旋转变换 Scale

玄机逸士的专栏 2万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

AndroidGUI26:程序中动态设定组件的宽度、高度以及margin等属性

在程序里面用代码来控制组件的宽度、高度以及margin等属性,以适应不同分辨率的屏幕。

玄机逸士的专栏 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

AndroidGUI27:findViewById返回null的解决办法

在用Eclipse进行Android的界面开发,通过findViewById试图获取界面元素对象时,该方法有时候返回null,造成这种情况主要有以下两种情形。   第一种情形是最普通的。比如main.xml如下,其中有一个ListView,其id为lv_contactbook

玄机逸士的专栏 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

AndroidGUI03:Spinner的常用技巧

关于Spinner控件的常见用法,包括在Item中出现Image和文字。

玄机逸士的专栏 1万+

AndroidGUI29:用getDrawingCache方法获取ImageView中的图像需要注意的问题

我们知道在Android中ImageView是一个用于显示图像的控件,比如在很多联系人方面的应用中,需要为联系人拍摄头像,并将得到的头像放在一个ImageView对象中显示。通常,在没有为联系人拍摄头像之前,ImageView对象中显示的是一个缺省的图片。因此,在保存联系人头像数

玄机逸士的专栏 1万+

Android中对Group的各种操作示例代码

1.  增加Group // create a group ContentValues values = new ContentValues(); values.put(ContactsContract.Groups.TITLE, “GROUPNAME”); Uri uri = getContentResolver().insert(ContactsContract.Groups.CONTENT

玄机逸士的专栏 1万+

AndroidGUI18:ListView常用技巧

ListView是AdapterView的派生类,AdapterView是ViewGroup的派生类。     ListView将需要显示的内容,放在一个可以垂直滚动的列表中进行显示。而要显示的内容是由和ListView相关联的ListAdapter指定的。通常是ArrayAdapter或者CursorAdapter,这两者都是ListAdapter的派生类。   因此ArrayAdap

玄机逸士的专栏 1万+

Android SDK安装时碰到的问题之解决办法

问题: hostname in certificate didn't match: != Fetching URL: https://dl-ssl.google.com/android/... 解决办法: 第一步: 打开Windows中C:\WINDOWS\system32\drivers\etc\hosts,Linux中/etc/hosts文件,然后添加以下内容: 203.20

玄机逸士的专栏 1万+
上一篇: AndroidGUI12:ContextMenu的常用技巧
下一篇: AndroidGUI14:各种Dialog常用技巧
pathuang68
博客等级 码龄18年 1821粉丝 194原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值