`
shappy1978
  • 浏览: 698456 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Kuix 焦点跳转分析

    博客分类:
  • J2ME
阅读更多

    先从一个案例入手我有一个界面,上面是列表,下面是一排按钮,列表的内容比较多,我希望按右键可以直接跳转到按钮,实际上一开始确实ok,后来换了一套Skin,按右键死活都不跳到下面的按钮了,转回原来的skin,又可以正常跳转.一开始拼命比对两个skin的样式表,没有发现明显的差异,相同的代码怎么可能造成不通的运行结果,答案就是代码造成的.

    对Kuix用的比较多的人会发现,Kuix的焦点跳转有点奇怪的地方,按左右键移动到屏幕最右边的控件后,会自动跳到下一个容器里面的控件,而且不是第一个控件,是离当前控件距离最近的控件.这理解起来是有一些道理的,因为多数手机是没有触摸屏的,依靠按键快速跳动的话,这种算法比较适用于普通人的视觉习惯,但是这个算法却存在不少问题,在特定的时候就会跳出来.

 

	/**
	 * Returns the previous or next focusable {@link Widget} according to the
	 * <code>forward</code> parameter.
	 * 
	 * @return The previous or next focusable {@link Widget}
	 */
	public Widget getOtherFocus(Widget root, Widget focusedWidget, Widget nearestFocusableWidget, boolean forward, Alignment direction, boolean checkItself, boolean checkChild, boolean checkParent) {
		boolean isVisible = isVisible();
		if (checkItself && root != this && !isFocused() && isFocusable() && isVisible) {
			if (focusedWidget == null || direction == null) {
				return this;
			}
			if (isNearest(focusedWidget, nearestFocusableWidget, direction)) {
				nearestFocusableWidget = this;
			}
		} else if (checkChild && isVisible) {
			// Children scan
			Widget childWidget = forward ? child : lastChild;
			if (childWidget != null) {
				nearestFocusableWidget = childWidget.getOtherFocus(root, focusedWidget, nearestFocusableWidget, forward, direction, true, true, false);
				if ((focusedWidget == null || direction == null) && nearestFocusableWidget != null) {
					return nearestFocusableWidget;
				}
			}
		}
		if (root != this) {
			// Brother scan
			Widget otherWidget = forward ? next : previous;
			if (otherWidget != null) {
				nearestFocusableWidget = otherWidget.getOtherFocus(root, focusedWidget, nearestFocusableWidget, forward, direction, true, true, false);
				if ((focusedWidget == null || direction == null) && nearestFocusableWidget != null) {
					return nearestFocusableWidget;
				}
			}
			// Parent scan
			if (checkParent && parent != null && isVisible) {
				nearestFocusableWidget = parent.getOtherFocus(root, focusedWidget, nearestFocusableWidget, forward, direction, true, false, true);
				if ((focusedWidget == null || direction == null) && nearestFocusableWidget != null) {
					return nearestFocusableWidget;
				}
			}
		}
		return nearestFocusableWidget;
	}

 这个是跳转焦点的函数,即使debug进去的话也相当难理解,因为是递归调用的,而且一般会嵌套相当多层,基本上也是按照正常的逻辑思维,现在同一容器中查找,目标控件是容器的话再查找里面的子控件,同级容器没有的话再转到上一级容器,而这个函数最主要的目标则是isNearest函数,判断两个控件的距离是不是最近的.

 

	private boolean isNearest(Widget originWidget, Widget nearestWidget, Alignment direction) {
		if (originWidget != null && direction != null) {
			int origX = originWidget.getDisplayX() + originWidget.visualCenterX;
			int origY = originWidget.getDisplayY() + originWidget.visualCenterY;
			int dx = getDisplayX() + visualCenterX - origX;
			int dy = getDisplayY() + visualCenterY - origY;
			if (nearestWidget != null) {
				int nearestDx = nearestWidget.getDisplayX() + nearestWidget.visualCenterX - origX;
				int nearestDy = nearestWidget.getDisplayY() + nearestWidget.visualCenterY - origY;
				if (direction.isTop() || direction.isBottom()) {
					if (Math.abs(dy) <= Math.abs(nearestDy) && dy != 0 && (direction.isBottom() && dy > 0 || direction.isTop() && dy < 0)) {
						if (Math.abs(dx) <= Math.abs(nearestDx)) {
							return Math.abs(dx) + Math.abs(dy) < Math.abs(nearestDx) + Math.abs(nearestDy);
						}
					}
				} else {
					if (Math.abs(dx) <= Math.abs(nearestDx) && dx != 0 && (direction.isRight() && dx > 0 || direction.isLeft() && dx < 0)) {
						if (Math.abs(dy) <= Math.abs(nearestDy)) {
							return Math.abs(dx) + Math.abs(dy) < Math.abs(nearestDx) + Math.abs(nearestDy);
						}
					}
				}
			} else {
				if (direction.isTop() || direction.isBottom()) {
					return dy != 0 && (direction.isBottom() && dy > 0 || direction.isTop() && dy < 0);
				} else {
					return dx != 0 && (direction.isRight() && dx > 0 || direction.isLeft() && dx < 0);
				}
			}
		}
		return false;
	}

    这个函数其实也不是太好理解,原意是根据两个控件的坐标差来判断,由于函数里面只是比较两个控件,所以实际上只是比较到某个方向上逐渐"靠近"过来的控件,一旦距离超过临界值0,就认为是最近的控件,实际上会造成一个问题,就是一旦"下一行"的最后一个控件中心比当前控件小(在比较的方向上),这个跳转就不成立.这就解释我上面碰到的"诡异"的问题.换了skin后,按钮的中心变化了,中心x坐标比列表的中心小,导致上面的跳转不能成立,实际上一旦下一列的最后一个按钮中心x坐标小于等于焦点控件的中心x坐标,跳转就会失败.

    解决方法:1 偷懒,增加下面列按钮的中心x坐标 2 修改Widget代码

    这个代码实际上还会造成一个问题,在屏幕较小的手机,而列表项为多行的文本时,按向下键移动到屏幕上最后一列时,滚动条不会滚动到下一列,而是跳转到下面的按钮栏了,滚动条下面的列表信息永远看不到了.

  • 大小: 18 KB
分享到:
评论

相关推荐

    EditText焦点的自动跳转

    本篇文章将详细讲解如何实现`EditText`焦点的自动跳转。 首先,我们需要了解`EditText`的基本属性和事件。`EditText`继承自`TextView`,添加了接收和显示用户输入的功能。它的焦点管理涉及到`FocusChangeListener`...

    焦点自动跳转时间控件

    本文将深入探讨一个特殊的实现——"焦点自动跳转时间控件",这是对标准CDateTimeCtrl类的一个扩展,它在用户输入过程中提供了更友好的交互体验。 CDateTimeCtrl是MFC(Microsoft Foundation Classes)库中提供的一...

    Android程序间Intent跳转分析

    本文将深入探讨Android程序间Intent跳转分析的相关知识点。 首先,Intent是Android系统中的一种消息对象,用于封装一个动作(Action)以及动作涉及的数据(Data)。在描述中提到的"跳转分析器"是一个开发者工具,它...

    各种的js跳转

    ### 各种JS跳转方式详解 在前端开发中,页面跳转是常见的需求之一,JavaScript(简称JS)提供了多种实现页面跳转的方法。本文将详细介绍由标题“各种的js跳转”及描述“总结了下js的跳转懒得找得就下的非常全···...

    Android程序间跳转分析器

    在这个分析器中,我们可以对多种常见的跳转行为进行跟踪和分析,如分享、选择本地图片、使用第三方应用打开文件以及跳转到应用市场等。 首先,让我们了解Android中的Intent机制。Intent是Android系统中用于启动活动...

    一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源

    一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转界面源码一款好看的即将跳转...

    jsp response.sendRedirect不跳转的原因分析及解决.docx

    ### jsp response.sendRedirect不跳转的原因分析及解决 #### 一、问题背景 在进行Web应用开发的过程中,经常需要使用到服务器端重定向的技术。在Java Server Pages (JSP) 技术中,`response.sendRedirect()` 是一...

    qt 界面跳转 界面跳转 界面跳转

    在QT编程中,界面跳转是一项关键技能,用于构建多页面的应用程序,使得用户可以在不同的功能模块间自由切换。QT库提供了丰富的工具和组件来实现这一功能,主要依赖于信号与槽机制、QStackedWidget、QWizard以及...

    相对跳转指令和绝对跳转指令的特殊用法

    #### 五、示例分析 假设有一段程序,其中包含了相对跳转指令BL和绝对跳转指令BX。在程序编译时,假设编译基地址为0xC0000000,但在实际运行时,程序却位于0x00000000地址开始的空间中。在这种情况下: 1. **相对...

    基于PHP的炫酷黑色网址安全跳转GO跳转PHP源码.zip

    【标题】"基于PHP的炫酷黑色网址安全跳转GO跳转PHP源码.zip" 提供的是一款使用PHP编写的网页安全跳转程序,它的设计风格是炫酷的黑色主题,能够实现用户从一个网址安全地跳转到另一个网址。在互联网应用中,这种跳转...

    APP间的相互跳转跳转

    在移动设备上,应用程序(APP)间的相互跳转是一项关键功能,它允许用户在不同的应用之间无缝切换,提升用户体验并促进各个应用之间的交互。本文将深入探讨如何实现APP间的相互跳转,包括基本原理、常见方法以及不同...

    PHP网站跳转链接页面源码 一般用在跳转到外部链接.

    在实际应用中,我们可能需要更灵活的处理,比如添加延迟跳转或者根据条件进行跳转。下面是一个带有延迟跳转的例子: ```php header("Refresh: 5; url=http://example.com"); echo "您将在5秒后被重定向到 新页面...

    归档_微信跳转_跳转PHP_跳转_

    在IT行业中,微信跳转是一种常见的应用场景,尤其在移动互联网时代,微信作为主流社交平台,其内置的浏览器已经成为用户访问网页的重要渠道。本压缩包文件包含的“微信跳转_跳转PHP_跳转”主题,是关于如何利用PHP...

    C#中所有页面跳转方式

    本文将详细介绍C#中的几种页面跳转方法,并针对每种方法的特点进行分析,以便开发者可以根据具体的应用场景选择最合适的方案。 #### 1. 使用`HyperLink`控件 `HyperLink`是一种常见的用于页面跳转的方法。通过设置...

    易语言取跳转地址

    6. **代码优化**:在某些情况下,获取跳转地址可能是为了进行代码优化,例如通过静态分析减少不必要的计算或跳转。 由于没有具体的源码内容,以上分析仅基于易语言的一般特性及“取跳转地址”和“取状态”的概念...

    路由技术解决页面跳转问题

    以我们公司现在这个项目为例,前台是由FLEX实现,整个系统可能只有几个application组成,所有的功能点均由module实现,而Module本身无法实现各module之间的跳转,只能通过application实现对各个module的动态加载来...

    易语言汇编跳转到标记源码

    4. **调试技巧**:学会使用易语言的调试工具,以便于查看和分析程序在运行时的跳转行为。 5. **性能优化**:理解何时应该使用汇编语言进行性能优化,以及如何通过跳转到标记实现高效的代码执行。 在实际操作中,...

    ASP实现网页跳转

    在ASP中,网页跳转是一种常见的操作,它允许用户在不同的页面之间进行导航。实现网页跳转通常有两种方法:Response.Redirect和Server.Transfer。 1. **Response.Redirect方法** `Response.Redirect` 是ASP中最常用...

    页面自定跳转 超链接 跳转 jsp页面跳转

    根据给定的文件信息,我们可以深入探讨页面自动跳转、超链接跳转以及JSP页面跳转的相关知识点,尤其关注于HTML、JavaScript以及浏览器兼容性处理。 ### 页面自定义跳转与超链接跳转 页面自定义跳转指的是在网页...

Global site tag (gtag.js) - Google Analytics