追溯源码解决android疑难问题2--寻找丢失的焦点

来源:互联网 发布:兄弟连java培训多少钱 编辑:程序博客网 时间:2024/05/29 16:27
在手机应用开发中,基本不用考虑焦点控制问题。但是在机顶盒,智能电视上,不支持手势滑动触摸体验,一切都需要使用遥控器操作。

所以一个TV上的应用是不是遥控器友好的,取决于应用对焦点的绝对控制。

在开发过程中,通常情况下的焦点控制是交给系统处理的,开发者通常处理的焦点问题多出现在以下几种情况中:

1.数据边界,如viewpager滚动到最左或者最右时

2.页面刚刚展现完毕,要求特定组件获得焦点

3.特殊的交互方式,比如左导航和右边页面的焦点切换,一般要求焦点智能记忆,如下图所示:



上一次我们深入源码去解决Viewpager的问题,继续深入源码,今天我们来说一下在scrollview中无限制滚动带来的焦点问题。

问题描述:在scrollview中无限制添加view,当scrollview的长度超过1万像素时,向上移动焦点时,必然出现焦点丢失问题。

这个问题本来是由于不正确的使用scrollview引起的,不应该如此无下限的向scrollview中加入如此多的组件。问题出在焦点查找类FocusFinder类中……

FocusFinder查找焦点有一系列复杂的算法,本人算法基础薄弱,有些算法看不懂,就不在这里露怯了,直接说有问题的地方。

在焦点查找的算法里,有如下一个算法:

    /**     * Fudge- factor opportunity: how to calculate distance given major and minor     * axis distances.  Warning: this fudge factor is finely tuned, be sure to     * run all focus tests if you dare tweak it.     */    int getWeightedDistanceFor( int majorAxisDistance, int minorAxisDistance) {               return 13 * majorAxisDistance * majorAxisDistance                + minorAxisDistance * minorAxisDistance;    }

不知道这个系数是如何计算出来的,但是有一个问题你可能一眼就看出来了,就是majorAxisDistance
这个参数如果特别大的话,取平方以后很有可能超过int类型数值的最大值,从而造成溢出,从而造成焦点找不到。

所以为了避免这种情况,我们需要修改FindFocus类,只好从android的源码中拎出来,单独使用。

修改如下:
   /**     * Fudge- factor opportunity: how to calculate distance given major and minor     * axis distances.  Warning: this fudge factor is finely tuned, be sure to     * run all focus tests if you dare tweak it.     */    long getWeightedDistanceFor( int majorAxisDistance, int minorAxisDistance) {      // avoid overflow. bysong        return 13L * majorAxisDistance * majorAxisDistance                + minorAxisDistance * minorAxisDistance;    }

使用时,调用FocusFinder.getInstance().findNextFocus()

搞定……



原文链接:http://www.67tgb.com/?p=626

转载注明:望月听涛

原创粉丝点击