【欢迎浏览和转载 Canon_Lee 的原创博客】
【http://blog.youkuaiyun.com/ljn951/article/details/46897281】
【我写文章写得时候会尽量写得通俗和基础,所以大神请见谅】
在Android的布局中,控制焦点在多个控件之间切换一直是一个重要的问题,因为如果一个控件没有获得焦点,那么它对应的事件响应也就不会被触发。
首先,是父控件和子控件之间焦点的控制,我们知道当一个点击事件发生的时候,父控件和子控件同样都可能会接收到这个事件。想要按照我们的要求来指定他们的获取顺序和权限,就要在父控件中设置 android:descendantFocusability 。
这个属性值是对于父控件(ViewGroup)而言的,所以几个选项的描述也是针对父控件,分别是先于子控件获得焦点、后于子控件获得焦点、获得焦点后拦截。
android:descendantFocusability =
beforeDescendants 先于子控件获得焦点
afterDescendants 后于子控件获得焦点
blocksDescendants 获得焦点后拦截
而在子控件与子控件之间的焦点切换,我这里也介绍两种方法。很多时候多个子控件会在布局中占据相同的位置(通过FrameLayout和RelativeLayout来实现),所以要控制它们的焦点切换单单靠点击动作可不够。
第一种切换方法,利用寻找nextfocus的方法进行切换。
Android中有nextfocus这个属性,并且分为六个方向。
android:nextFocusUp="@+id/XXX"
android:nextFocusLeft="@+id/XXX"
android:nextFocusRight="@+id/XXX"
android:nextFocusDown="@+id/XXX"
android:nextFocusForward="@+id/XXX"
android:nextFocusBackward="@+id/XXX"
这些属性值可以主动设置,也可以由系统自动为其分配。
既然知道了每一个控件各方向上下一个focus的控件是什么,那么就可以使用focussearch()来获得这些控件的实例,接着用它们请求焦点就行了。
View v = this.focusSearch(FOCUS_FORWARD);
v.bringToFront();
v.requestFocus();
另外一种方法则是通过父控件遍历的方式来切换子控件的焦点。切换焦点的关键无非就是拿到目标控件的实例,既然两个子控件是属于同一个父控件的,那么就可以通过父控件遍历来找到另一个子控件。
public View findNextChild(View v) {
int index1 = this.indexOfChild(v);
View child;
if(index1<this.getChildCount()-1) {
child = this.getChildAt(index1+1);
} else {
child = this.getChildAt((index1+1)-this.getChildCount());
}
return child;
}
在父控件中加入这个函数,那么它的子控件只需要调用这个函数,就可以轻松的找到下一个子控件了。