如何让Button更具响应性?

时间:2011-02-18 10:41:44

标签: android user-interface

我注意到有些按钮看起来并不像它们那样响应。这同样适用于我的应用以及我尝试过的大多数其他应用。

当我按下一个按钮时,在按钮状态下按钮亮起之前会有一点点延迟(编辑:我估计大约20-50毫秒)。一些应用程序设法消除了这一点滞后,例如RealCalc(市场上有售),当你按下手指按钮后,按钮会立即切换到按下状态。

大多数情况下,这种延迟并不明显,但在我使用按钮用于自定义数字键盘的情况下,这一点点的延迟对用户来说是一种破坏性的。 RealCalc感觉如此响应和抛光,因为这种滞后已被消除。

我的问题是 - 如何消除这种滞后?我知道我可以只是子类,覆盖onTouchEvent并从那里继续,但我真的更喜欢只使用标准控件和选项的解决方案。我怀疑解决方案也可能会干扰滚动,但我可以忍受。

编辑:具体来说,提到的延迟是指将手指放在按钮上并按住按钮直到按钮切换到按下状态的时间。再次移开手指时会调用onClick处理程序。

一些答案​​建议将我的onClick处理程序的大部分移动到一个线程。这不是问题。为了更加确定,我已经删除了所有点击处理程序,并且仍然存在微小的延迟。

4 个答案:

答案 0 :(得分:15)

我已经挖掘了Android源代码,看看发生了什么。

事实证明,android.view.View类(Button派生的类)在进入PRESSED状态之前进入“PREPRESSED”状态:

android.view.View:

1529    /**
1530      * Indicates a prepressed state;
1531      * the short time between ACTION_DOWN and recognizing
1532      * a 'real' press. Prepressed is used to recognize quick taps
1533      * even when they are shorter than ViewConfiguration.getTapTimeout().
1534      * 
1535      * @hide
1536      */
1537     private static final int PREPRESSED             = 0x02000000;
在我的Nexus One上,

android.view.ViewConfiguration.getTapTimeout()是115毫秒,这比我估计的要长很多。

android.view.ViewConfiguration:

67     /**
68      * Defines the duration in milliseconds we will wait to see if a touch event 
69      * is a tap or a scroll. If the user does not move within this interval, it is
70      * considered to be a tap. 
71      */
72     private static final int TAP_TIMEOUT = 115;

无论如何,从检查View.onTouchEvent看起来并不像是有办法通过任何标准选项来避免这种PREPRESSED状态。这真是一种耻辱。

好消息是我现在已经确认避免这种延迟的方法是子类化并覆盖onTouchEvent。

感谢您的讨论和答案。

答案 1 :(得分:8)

这似乎解决了这个问题:

public boolean onTouchEvent (MotionEvent event) {
   if (event.getAction() == MotionEvent.ACTION_DOWN) setPressed(true);
   return super.onTouchEvent(event);
}

仍然不完美,但更好。

答案 2 :(得分:3)

嗯...我通常扩展Button类并覆盖onTouchEvent方法

public boolean onTouchEvent (MotionEvent event) 
{
   if (event.getAction() == MotionEvent.ACTION_DOWN) 
   {
      setPressed(true);
   }
   return super.onTouchEvent(event);
}

答案 3 :(得分:0)

所以在任何Android应用程序中基本上都会发生GUI在主线程中运行。如果你碰巧在同一个线程中运行其他一些重要的东西,比如通信,视频,循环等,这些活动肯定会减慢你的GUI速度。 这在我的应用程序中发生过,然后我将所有其他进程分别移动到一个单独的线程,GUI变得非常实时响应。