在上一篇中我们已经创建出一个运行在盒子上的APP,它和我们运行在手机上的APP区别极小,只有在Manifest.xml中有些许的不同。但是我们知道,TV和手机最大的区别就在于交互,在手机APP内,我们可以通过注册点击监听onClickListener,或者是触摸OnTouchListener来进行交互,但是Tv上显然是没有触摸的,至少是没有onTouchListener的。
取而代之的是焦点事件,onFocusChangeListener,当一个控件焦点发生改变的时候,我们需要做些什么操作。这是TV开发的重点。
那我们要怎样来处理焦点呢?
1.在布局中直接指定,注意,布局中控件必须是可获取焦点的:focusable = "true"
nextfocusLeft、nextfocusRight、nextfocusUp、nextfocusDown分别用来指定:当焦点位于此按钮时,在按上下左右四个方向键,获取焦点的控件。相似的,也可通过代码来指定,如下:
这样处理之后的View就可以获取焦点。
但是仅仅这样来处理是不够的,我们指定了焦点,但是在屏幕上我们要如何给用户提供视觉上的提示,即当前获取焦点的是哪个控件呢?
2.这时就需要对控件添加焦点变化监听:setOnFocusChangeListener();
在监听里,我们可以对控件进行处理,比如,我们希望获取焦点的控件变大,则可以继续这样来写:
main_tv_left.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus){
v.setScaleX(1.1f);
v.setScaleY(1.1f);
}else {
v.setScaleX(1.0f);
v.setScaleY(1.0f);
}
}
});
但是,问题又出现了,如果页面中只有一两个控件需要添加监听这样做还是可以的,但是,如果页面中有十几二十几个控件都需要监听焦点变化,我们一个一个来写显然是太麻烦了。
那有没有什么简便的方法来处理焦点监听呢?当然是有的。
3.监听全局的焦点:ViewTreeObserver.OnGlobalFocusChangeListener
要监听全局的焦点变化,我们就需要给我们的根布局加上OnGlobalFocusChangeListener监听。
3.1 使当前Activity implements ViewTreeObserver.OnGlobalFocusChangeListener,并实现其方法。
3.2 为根布局添加监听。
ViewTreeObserver viewTreeObserver = main_rootview.getViewTreeObserver();
viewTreeObserver.addOnGlobalFocusChangeListener(this);
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if(newFocus == null) return;
if (oldFocus!=null){
AnimationUtils.viewToNormal(oldFocus);
}
AnimationUtils.viewGetFocus(newFocus);
}
在onGlobalFocusChanged()里,需要注意oldFocus 为null的情况,因为我们刚进入页面的时候,其实已经有一个view获取到了焦点,但是此时是没有oldFocus的。
好了,到现在为止,我们已经可以监听全局的焦点,至于获取到焦点之后,则只需要对控件做点击处理即可,这一部分和手机APP上的处理是一致的,即添加onClickListener(),在此不做细表。