<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.lindingdu.app17.SpiritlevelView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.util.Printer;
import android.view.View;
public class SpiritlevelView extends View implements SensorEventListener {
private Bitmap bubble;//小篮球位图对象
float[]accV=new float[3];//加速度传感器的值
float[]magV=new float[3];//磁场传感器的值
private int Max=30;//手机最大倾斜角度
private int bx,by;//篮球的位置坐标
public SpiritlevelView(Context context,AttributeSet attrs) {
super(context, attrs);
SensorManager sensorManager = (SensorManager) context
.getSystemService(Context.SENSOR_SERVICE);//获取传感器管理器
sensorManager.registerListener(this
,sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
,SensorManager.SENSOR_DELAY_GAME);//为磁场传感器注册监听器
sensorManager.registerListener(this
,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
,SensorManager.SENSOR_DELAY_GAME);//为加速度传感器注册监听器
//加载篮球图片
bubble= BitmapFactory.decodeResource(getResources(),R.drawable.bubble);
}
@Override
public void onSensorChanged(SensorEvent event) {//值改变时触发
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
accV=event.values.clone();
}else if(event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){
magV=event.values.clone();
}
float R[]=new float[9];//保存旋转数据的数组
float values[]=new float[3];//保存方向数据的数组
SensorManager.getRotationMatrix(R,null,accV,magV);//获得一个包含旋转矩阵的R数组
SensorManager.getOrientation(R,values);//获取方向值
float x=(float)Math.toDegrees(values[1]);//x轴旋转角度
float y=(float)Math.toDegrees(values[1]);//y轴旋转角度
getPosition(x,y);
super.postInvalidate();//刷新界面
}
public void getPosition(float X,float Y){
//篮球位于水平中心是,xy的坐标
int x=(super.getWidth()-bubble.getWidth())/2;
int y=(super.getHeight()-bubble.getHeight())/2;
//控制球X轴的位置
if(Math.abs(Y)<=Max){//如果Y轴的最大倾斜角度在最大角度之内
//根据Y轴的倾斜角度计算X坐标的变化值(倾斜角度越大,X坐标变化越大)
int deltaX=(int)((super.getWidth()-bubble.getWidth())/2*Y/Max);
x-=deltaX;
}else if(Y>Max){//Y轴倾斜角度大于最大倾斜角度,小球在最左边
x=0;
}else{//Y轴倾斜角度小于负的最大倾斜角度,小球在最右边
x=super.getWidth()-bubble.getWidth();
}
//控制球Y轴的位置
if(Math.abs(X)<=Max){
int deltaY=(int)((super.getHeight()-bubble.getHeight())/2*X/Max);
y+=deltaY;
}else if(X>Max){//x轴倾斜角度大于max篮球在最下边
y=super.getHeight()-bubble.getHeight();
}else{//x轴的倾斜角度小于负的max,篮球在最上边
y=0;
}
//更新小球坐标
bx=x;
by=y;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bubble,bx,by,new Paint());//绘制篮球
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
网友评论