Android ViewTreeObserver的常用技巧

原文地址: https://blog.csdn.net/geekzhe/article/details/47003811

Aview tree observer is used to register listeners that can be notified of globalchanges 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 isprovided by the views hierarchy. Refer toView.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.    创建一个AndroidProject,修改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代码如下:

publicclass 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;

privatebooleanbtnClicked;

@Override

publicvoid 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

publicvoid onTouchModeChanged(boolean isInTouchMode)

{

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

elsetv_show.setText("Not in touch mode");

}

// onGlobalLayout是接口ViewTreeObserver.OnGlobalLayoutListener

// 中定义的方法。

// Callback method to be invokedwhen the global layout state or the

// visibility of views within the viewtree changes

@Override

publicvoid onGlobalLayout()

{

if(btnClicked)

{

if(!ed2.isShown())

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

else

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

}

}

// onPreDraw是接口ViewTreeObserver.OnPreDrawListener

// 中定义的方法。

@Override

publicboolean onPreDraw()

{

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

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

ed1.setTextSize((float) 20.0);

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

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

}

// onGlobalFocusChanged是接口ViewTreeObserver.OnGlobalFocusChangeListener

// 中定义的方法。

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

@Override

publicvoid onGlobalFocusChanged(View oldFocus, ViewnewFocus)

{

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

{

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

}

}

@Override

publicvoid 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 intouch mode变成了In touchmode,二是显示了焦点变化方面的信息。它们分别是onTouchModeChanged和onGlobalFocusChanged这两个方法所输出的信息。

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

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

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

原文地址:https://www.cnblogs.com/l-h-h/p/10438327.html

时间: 2024-10-07 07:15:31

Android ViewTreeObserver的常用技巧的相关文章

Android之ListView常用技巧

ListView是一个非常常用的列表控件,虽然在5.x时代ListView的风头正在逐渐的被RecyclerView抢去,但是ListView的使用范围依然十分广泛. 接下来的ListView的常用技巧是在平时的开发和学习中了解到的,如有雷同,纯属我抄! 技巧1:设置项目间分隔线 技巧2:隐藏滚动条 技巧3:设置第一个可视条目是第几项 技巧4:添加/取消item的点击效果. 技巧5:处理数据项为空的时候的ListView 技巧6:动态更新ListView 下面依次介绍 1.设置项目间的分割线 这

ViewTreeObserver的常用技巧

Aview tree observer is used to register listeners that can be notified of globalchanges 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 ViewTreeObser

android 布局优化常用技巧

android对多个模块都要是要的UI逻辑的致辞除了fragment之外,没有别的东西可以支持了, include,merge,viewstub只能支持公用的ui,但是这个通用支持不能包含逻辑(java代码)的. 1.使用include标签 这个标签只是启动重复某个UI xml文件的作用,android框架在解析的时候没有什么优化,唯一的作用就是起到方便管理的作用了. 当解析到 include 标签的时候,就从它的layout属性中拿出 布局文件,解析这个布局,替代include标签的节点 2.

Android EditText的常用技巧

1.       设定 EditText 的滚动条.对齐方式.行数.和提示 (hint) 及其颜色 在布局文件,比如 main.xml 中,增加 < EditText android:id = "@+id/EditText01" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:hint = "type somet

Android UI 中常用技巧总结

线性布局 分割线 android:divider="@drawable/shape"<!--分割线图片--> android:showDividers="middle|beginning|end" <!--分割线位置-->

最强 Android Studio 使用小技巧和快捷键【非原创】

(发现本文是个很不错的文章,相当实用,特分享与大家.分享自:http://m.open-open.com/m/lib/view/1458715872710.html 特此声明,好记性不如烂笔头,market下来以备后用) 原文如下: 写在前面 本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android Studio 使用小技巧和快捷键. 根据这些小技巧的使用场景,本文将这62个小技巧分为常用技巧(1 – 28).编码技巧(29 –

Android Studio 使用小技巧和快捷键

Alt+回车 导入包,自动修正 Ctrl+N   查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L  格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如get,set方法,构造函数等) Ctrl+E或者Alt+Shift+C  最近更改的代码 Ctrl+R 替换文本 Ctrl+F 查找文本 Ctrl+Shift+Space 自动补全代码 Ctrl+空格 代码提示 Ctrl+Alt+Space 类名或接口名提示 Ctrl+P 方法参数提示 Ctr

最强 Android Studio 使用小技巧和快捷键

写在前面 本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android Studio 使用小技巧和快捷键. 根据这些小技巧的使用场景,本文将这62个小技巧分为常用技巧(1 – 28).编码技巧(29 – 49)和调试技巧(50 – 62),分成三个部分. 每个小技巧都配有 gif 动图,由于原图在 google photo 上,加载较慢,本文全部转存到七牛上了. 由于能力有限,翻译过程中难免有所疏漏,如发现错误或问题,请在评论中提出

HTML5-移动开发常用技巧与弹性布局的使用

一.移动开发常用技巧 Viewport基本知识 设置布局Viewport的各种信息 1.width=device-width: 设置Viewport视口宽度等于设备宽度 2.initial-scale=1: 网页默认缩放比为1(网页在手持设备上,不会进行默认缩放 3.minimum-scale=1 网页最小缩放比为1 4.maximum-scale=1 网页最小大缩放比为1 5.user-scalable=no 禁止用户手动缩放网页(ios10+ 的设备失效) 在手机站及响应式网站的制作中,网页