AndroidGUI13:ViewTreeObserver的常用技巧
2011-05-19 01:28
531 查看
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
方法中设定的。
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
方法中设定的。
相关文章推荐
- AndroidGUI13:ViewTreeObserver的常用技巧
- AndroidGUI13:ViewTreeObserver的常用技巧
- AndroidGUI13:ViewTreeObserver的常用技巧
- Android ViewTreeObserver的常用技巧
- Android ViewTreeObserver的常用技巧
- (一)Android ViewTreeObserver的常用技巧
- ViewTreeObserver的常用技巧
- Android View中getViewTreeObserver().addOnGlobalLayoutListener()
- Android ViewTreeObserver
- Android GUI系统-ViewTree的遍历(四)
- Android ViewTreeObserver简介
- Android TextView 常用技巧
- 关于Android中的ViewTreeObserver
- 关于Android中的ViewTreeObserver
- Android ViewTreeObserver简介
- 【安卓】android.view.ViewTreeObserver.OnGlobalLayoutListener
- 解析 ViewTreeObserver 源码,体会观察者模式、Android消息传递(上)
- Android 下拉刷新(使用异步任务和ViewTreeObserver监听)
- android ViewTreeObserver详细讲解
- Android通过ViewTreeObserver获得输入法键盘弹起后可见区域高度