這兩天公司項目需要效果是實現水平儀效果,從網上查了查,也找了一些儲備,雖然達到了要求,但是有點不足,和我需求不符合,就是當小球轉到邊緣的時候,小球會在邊緣不動,於是就改了改,完美達到了我的要求,不管你手機怎麼轉,小球始終在大圓裏面,超過邊緣的時候,也是在邊緣滾動哦,特在此記錄,有需要的可供參考,廢話不多說,下面直接上代碼了:
還是要聲明下,這是本人第一篇博客,寫的不好,勿怪
呃,自己要提前準備兩張圖片哦,一張是小球的,一張是小球的背景畫布
實現的效果如下
1、首先定義傳感器變量
private Sensor gyroSensor = null;
2、在onCreat裏面初始化傳感器//初始化方向傳感器
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
3、在onResume裏面註冊傳感器
@Override
protected void onResume() {
super.onResume();
if (null != sensorManager || null != gyroSensor) {
sensorManager.registerListener(this, gyroSensor, SensorManager.SENSOR_DELAY_GAME); //爲傳感器註冊監聽器
}
}
4、onPause裏面要暫停傳感器@Override
protected void onPause() {
// 取消方向傳感器的監聽
if (null != sensorManager) {
sensorManager.unregisterListener(this);
}
super.onPause();
}
5、編寫PlaneView,這個就是水平儀的控件,這個是從網上摘抄的,不懂可以直接搜android 水平儀實現,一定有的
public class PlaneView extends View {
// 定義水平儀儀表盤圖片
public Bitmap back;
// 定義水平儀中的氣泡圖標
public Bitmap bubble;
// 定義水平儀中氣泡 的X、Y座標
public float bubbleX, bubbleY;
public PlaneView(Context context, AttributeSet attrs) {
super(context, attrs);
// 加載水平儀圖片和氣泡圖片
back = BitmapFactory.decodeResource(getResources(), R.mipmap.plane);
bubble = BitmapFactory.decodeResource(getResources(), R.mipmap.bubble);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 繪製水平儀表盤圖片
canvas.drawBitmap(back, 0, 0, null);
// 根據氣泡座標繪製氣泡
canvas.drawBitmap(bubble, bubbleX, bubbleY, null);
}
}
6、下面就是將控件放到你的Activity佈局中去,我的是MainActivity,佈局android_main.xml
<!-寬高在這裏設定,具體根據你個人項目需求->
<RelativeLayout
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="25dp">
<cn.leadpcom.com.underparking.common.PlaneView
android:id="@+id/pv_bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
7、下面就是具體在傳感器接收到數據之後的操作了,裏面的pv_bubble是我的控件名,大家應該懂得,轉換成你個人設定的就行,呃,實在不懂,我也沒有辦法啊,就是這裏面的邏輯和網上不同,希望大家注意哦,大家是不是在想MAX_ANGLE在哪裏,是什麼,哈哈,這個是定義的變量,就是角度,越小,小球就越靈敏
private int MAX_ANGLE = 10;//具體多大,自己嘗試下就行了
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 獲取觸發event的傳感器類型就
int sensorType = event.sensor.getType();
switch (sensorType) {
case Sensor.TYPE_ORIENTATION:
// 獲取與Y軸的夾角
float yAngle = values[1];
// 獲取與Z軸的夾角
float zAngle = values[2];
// 氣泡位於中間時(水平儀完全水平),氣泡的X、Y座標
int x = (pv_bubble.back.getWidth() - pv_bubble.bubble.getWidth()) / 2;
int y = (pv_bubble.back.getHeight() - pv_bubble.bubble.getHeight()) / 2;
// 根據與Z軸的傾斜角度計算X座標的變化值(傾斜角度越大,X座標變化越大)
int deltaX = (int) ((pv_bubble.back.getWidth() - pv_bubble.bubble.getWidth()) / 2 * zAngle / MAX_ANGLE);
x += deltaX;
// 根據與Y軸的傾斜角度計算Y座標的變化值(傾斜角度越大,Y座標變化越大)
int deltaY = (int) ((pv_bubble.back.getHeight() - pv_bubble.bubble.getHeight()) / 2 * yAngle / MAX_ANGLE);
y += deltaY;
// 如果計算出來的X、Y座標還位於水平儀的儀表盤內,更新水平儀的氣泡座標
float aa = (float) Math.sqrt((x - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) * (x - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) + (y - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)) * (y - (pv_bubble.back.getHeight() / 2 - pv_bubble.bubble.getHeight() / 2)));
if (aa < pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) {
pv_bubble.bubbleX = x;
pv_bubble.bubbleY = y;
} else {
float newx = (float) ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) * (x - (pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)))) / aa + ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)));
float newy = (float) ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)) * (y - (pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)))) / aa + ((pv_bubble.back.getHeight() / 2 - (pv_bubble.bubble.getHeight() / 2)));
pv_bubble.bubbleX = newx;
pv_bubble.bubbleY = newy;
}
// 通知系統重回MyView組件
pv_bubble.postInvalidate();
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
8、好了,只要按照上面的說的,應該就能完美實現了,小球一直在畫布裏面的哦!~!~!~!~!有需要的,參考下,大神還請給出點評,我會繼續更新改正,上面部分是摘抄,別的部分是原創,如有雷同,純屬巧合!~!~!~!~!~!