最近在開發一個基於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;
}
}
}