8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前面三篇都是从源码的角度分析按键事件、焦点变换的原理,作为应用层的开发者,

分析源码都是带着实际的开发困惑的,要不然谁没事做会read the fucking source code,

今天就分享一个Android TV开发中的解决的焦点移动问题。

起因

使用过奇异果TV应用的同学会发现它有焦点换行的功能,就是当一直按遥控器右键时焦点View会换行到下一行的第一个View,如下

使用体验很好,重要的是产品同学也觉得很好。

看到这个效果,我的第一直觉是给每个View设置Id,Id从左到右、从上到下增加,或者给每个View设置自增的Tag,

每次都去寻找Id + 1或者Tag +1的View,然后让它获得焦点,这不就OK了。

但这还是没有优雅的解决问题,只是把问题抛给了后台、运营,让他们一个一个的设置运营位的编号。

那有没有成本很小的解决方法呢?

getFocusedRect方法

上一篇的分析中我们知道当按键事件要转换成焦点移动时,需要在众多的View中寻找一个位置

最合适的View,然后让它获得焦点。而这个位置的依据是什么?其实就是每个View的getFocusedRect返回的Rect,

对于当前有焦点的View,用这个返回的Rect计算它搜寻的起始位置;对于没有焦点的View,用

这个Rect来表示自己当前的位置。View的这个方法的代码如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14* When a view has focus and the user navigates away from it, the next view is searched for

* starting from the rectangle filled in by this method.

*

* By default, the rectangle is the {@link #getDrawingRect(android.graphics.Rect)})

* of the view. However, if your view maintains some idea of internal selection,

* such as a cursor, or a selected row or column, you should override this method and

* fill in a more specific rectangle.

*

* @param r The rectangle to fill in, in this view's coordinates.

*/

public void (Rect r){

getDrawingRect(r);

}

实际上默认返回的就是View的绘制区域,但注释也说了可以根据实际的需要自己修改,那我就有一些想法了:可以根据View在不同的位置返回不同的Rect。

原理与实现

1.原理对于有焦点的View,如果它没靠近屏幕的边缘,这个方法返回实际的绘制区域

对于有焦点的View,如果它靠近屏幕的右边缘,将这个Rect移动到下一行的左侧屏幕的左外侧,左边缘的View同理

对于没有焦点的View,这个方法返回实际的绘制区域

这样当在右边缘的View上按右键时,实际上它的搜寻的起始位置在下一行的左外侧,位置最合适的View就是下一行第一个View,这样就可以花很小的代价解决这焦点换行的问题。

原理图如下:

当View在屏幕右边缘时,将Focus Rect的top设置为自己的botom的位置、Rect的right设置为0,

实际的搜索起始Rect是黑色虚线的Rect(原理可看上篇的分析),这样最合适的获得焦点的View就是第二行的第一个View,

达到了换行的目的

2.实现

重写View的getFocusedRect方法如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34public final void (Rect r){

//如果有焦点

if (isFocused()) {

//获得根View的绘制区域

rootView.getDrawingRect(mRootViewRect);

//获得自己的绘制区域

getDrawingRect(mTempDrawingRect);

//转换自己的绘制区域到根View的坐标系中去,方便计算FocusedRect的位置

rootView.offsetDescendantRectToMyCoords(this, mTempDrawingRect);

//判断自己是否满足换行的条件,1)按右键 2)自己在屏幕的右边缘

if ((mTempDrawingRect.right + 20) > mRootViewRect.right && currentKeyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

//重新获取自己的位置

getDrawingRect(mTempDrawingRect);

//转换根View的坐标系中去

rootView.offsetDescendantRectToMyCoords(this, mTempDrawingRect);

//将这个Rect移动到自己的下方、左侧屏幕的左外侧

mTempDrawingRect.left = 0 - getMeasuredWidth();

mTempDrawingRect.right = 0;

mTempDrawingRect.bottom = mTempDrawingRect.bottom + getMeasuredHeight();

mTempDrawingRect.top = mTempDrawingRect.top + getMeasuredHeight();

//将focus rect的坐标系还原到自己的坐标系

rootView.offsetRectIntoDescendantCoords(this, mTempDrawingRect);

r.set(mTempDrawingRect);

} else if (mTempDrawingRect.left - 20 < mRootViewRect.left && currentKeyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

//左键同理

......

} else {//没有在左右边缘或者没有按对应的左右键

super.getFocusedRect(r);

}

} else {//没有焦点

super.getFocusedRect(r);

}

}

android 按键分析,Android TV开发按键与焦点深入分析(四)相关推荐

  1. android listview 分析,Android中ListView用法实例分析

    本文实例分析了Android中ListView用法.分享给大家供大家参考,具体如下: 通过在Layout中添加ListView Widget可以达到在页面布局具有列表效果的交互页面.在这里通过举例来说 ...

  2. android 图库分析,Android开发之ImageSwitcher相册功能实例分析

    本文实例讲述了Android开发之ImageSwitcher相册功能.分享给大家供大家参考,具体如下: 简介: 1.ImageSwitcher是viewSwitcher的子类,所以ImageSwitc ...

  3. android dumpsys 分析,Android开发调试性能分析工具:dumpsys

    dumpsys可以用来查看android系统运行过程中的信息状态,如CPU.内存使用.... 例1:查看dumpsys的"子命令" adbshell dumpsys | grep ...

  4. ios android安全性分析,Android与iOS的对比分析及Android安全技术的设计与实现

    摘要: 近年来科技的发展和进步极大的推动了智能手机的飞速发展,手机功能的日益强大使人们对其依赖度显著上升.作为与人们生活密不可分通讯工具,手机安全的重要性不言而喻.现如今,随着手机网络的迅猛发展和形形 ...

  5. android adb 分析,android adb shell常用脚本分析课件.ppt

    android adb shell常用脚本分析课件 ADB概要 Android 调试系统是一个面对客户服务系统,包括三个组成部分: 电脑上运行的客户端. 在你用于开发的机器上作为后台进程运行的服务器. ...

  6. android gc分析,android GC浅析

    在dalvik中,GC的类型有三种: 1.GC_EXPLICIT: 应用主动调用System.gc()产生的GC事件. 2.GC_FOR_ALLOC: 3.GC_CONCURRENT: 给Java层的 ...

  7. android apk 分析,Android APK分析工具

    1.Apktool 官网:http://ibotpeaches.github.io/Apktool/ 源码: Github地址:https://github.com/iBotPeaches/Apkto ...

  8. android latinime分析,Android AOSP输入法(LatinIME)大写判断分析

    LatinIME源码地址:https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/android-5.1. ...

  9. 【Android 逆向】Android 系统文件分析 ( Android 系统 root 环境准备 | 查看 Android 根目录信息 )

    文章目录 一.Android 系统 root 环境准备 二.查看 Android 根目录信息 一.Android 系统 root 环境准备 需要一部 root 过的手机 , 或者直接使用带有 root ...

最新文章

  1. Git合并和变基简介:它们是什么,以及如何使用它们
  2. 2015#183;Fool#39;s Day#183;NND
  3. 用批处理编译*.sln工程(转)
  4. 本地IDC机房数据库容灾解决方案
  5. python:字典,元组
  6. POSIX线程的同步
  7. PHP如何添加变量 $_SERVER
  8. Windbg教程-调试非托管程序的基本命令上
  9. 脸部螨虫和肥皂洗脸的问题
  10. 2017计算机软件考试试题,2017年计算机应用考试试题含答案.doc
  11. hadoop--MapReduce_WordCount词频统计案例
  12. 印象笔记支持Markdown语法
  13. 华为云PBX_基于华为云客服平台打造的比特百灵鸟AI管家解决方案发布
  14. [转帖]怎样选择(FC-SAN)光纤通道(存储)交换机
  15. 培训班作业---作业1:公羊母羊生小羊的问题
  16. 程序员离职原因的最佳回答_转行面试,高情商回答“你为什么要离职?”(建议收藏)...
  17. mysql rpl_MySQL rpl_semi_sync_master_timeout相关的一件BUG
  18. linux病毒通过U盘传播,一个通过U盘传播的病毒详细分析,近期抓的但是是09年的病毒...
  19. cython混淆加密
  20. 解决win2008 R2远程桌面授权过期的方法

热门文章

  1. 【春节歌曲回味 | STM32小音乐盒 】PWM+定时器驱动无源蜂鸣器(STM32 HAL库)
  2. 第三天打卡--非线性规划(1)
  3. Firefox 设置
  4. spring cloud ribbon源码解析(一)
  5. Python写得好,壁纸无烦恼!
  6. float表设计长度_Hash函数设计及面试题分析
  7. java计算机毕业设计教师职称评定系统源码+mysql数据库+系统+lw文档+部署
  8. 计算机丢失strom.dll,win10玩暗黑破坏神2缺少storm.dll怎么解决
  9. 测试网页兼容性时如何选择浏览器
  10. 添加两个tomcat 并能同时运行,修改