最近在开发一个基于android操作系统的 播放器, 根据我 抽风一样的 设计理念 “更少,更大的按钮”,在第二次更改UI后, 主界面的按钮 被缩减成 3个: 帮助 按钮 ,播放/暂停 以及 音量控制
预计这三个按钮还会再一次缩减的,到2个,甚至一个,反正这就是我的“UI设计思想”,我觉得挺好看的。
删是删了,关键是如何实现 被删按钮的 功能……
打开文件的这一步,我是使用 "shake"这个动作来实现的,摇摆一下手机,之前编写好的一个 打开文件的activity就会被启动
在SDK中,google提供了这样一个接口,我们可以使用
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
看这几个包的名字就可以大体的知道,这与sensor有关
在我的相关activity实现SensorListener接口
public class HelloBear extends Activity implements SensorListener
这里 我得到了一个警告,google不建议你使用这个接口,建议你换另外一个可以实现相同功能的……额~算了,就用这个吧……哈哈
之后,在oncreate中注册一下下
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.registerListener((SensorListenerthis,SensorManager.SENSOR_ACCELEROMETER,SensorManager.SENSOR_DELAY_GAME);
根据接口的名称,既然是监听,那就需要对于动作的判断……
当时在写这一段的时候,借鉴刊载在 javaeye上的 一段,非常抱歉我把作者名字给忘记了……但是大体的实现过程是:
因为这个接口中,并没有专门用于shake动作的判断,而是仅仅给出了 x y z 的一个三维的矢量,思路是,间隔的测量这个三维的矢量,然后求出一个变化速度~ (定义三方向都有变化速度才叫摇摆),当这个速度达到了某个临界值的时候,动作被触发,我的动作是,intent 到另一个 activity
其实想到这里,我觉得应该没有什么大问题了,当实现了之后,才发现,一个非常非常严重失误,甚至是错误。
我们知道,在用户摇摆手机的时候,不可能速度的最大值是你设定的临界值,一般情况是,在到达临界值之后,速度还会增长,如果不加以控制的话,这个动作可能会被连续的执行
在不加控制的情况下,我试验的结果是:我的intent基本平均要被执行3-5次……
如何解决这个问题呢?或许我的解决方案没有普适性,因为我并没有 完全基于在一个activity里面解决问题,但是可以供参考~因为我们要做的很多意图都是activity之间切换
在监听判断时 加入一个boolean 标志 ,常态下为true ,在打开(动作发生)后,置为flase,在(动作打开)的activity被销毁后,再置为true,这里需要用到activityForResult
如:intent.setClass(HelloBear.this, ChooseBear.class);
HelloBear.this.startActivityForResult(intent, 0);
然后在onActivityResult中置标志为常态
问题得以解决
最后,贴一下,实现shake的核心代码~基本和javaeye上的一样,只是进行了上述优化(这个算法本身很简单很直观但是很SB~我希望找到更强大的算法)
public void onSensorChanged(int sensor,float[] values)
{
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// 每10毫秒检测一次
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
if (speed > SHAKE_THRESHOLD&& shakable ==true )
{
Intent intent = new Intent();
intent.setClass(HelloBear.this, ChooseBear.class);
HelloBear.this.startActivityForResult(intent, 0);
shakable = false;
cancelDelayHide();
}
last_x = x;
last_y = y;
last_z = z;
}
}
}