一、创建自定义View PointerView类,并且根据x轴和y轴磁场强度绘制指针
public class PointerView extends View implements SensorEventListener { private SensorManager sensorManager; private Bitmap pointer; private float[] allValue; public PointerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); //为磁场传感器注册监听器 sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), sensorManager.SENSOR_DELAY_GAME); //指定要绘制的指针位图 pointer = BitmapFactory.decodeResource(getResources(), R.drawable.magnetic); } //当传感器的值发生变化时,触发 @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { //获取磁场传感器的值 float[] value = event.values; allValue = value; //刷新界面 postInvalidate(); } } //当传感器的精度改变时,触发 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //根据x轴 y轴的磁场强度绘制指针 if (allValue != null) { //x轴的磁场强度 float x = allValue[0]; //y轴的磁场强度 float y = allValue[1]; canvas.save(); //重置绘图对象前面应该先调用canvas.save(); //否则会报Underflow in restore - more restores than saves错误 canvas.restore(); //设置旋转的中心点,为屏幕的中心点 canvas.translate(getWidth() / 2, getHeight() / 2); if (y == 0 && x > 0) { //表示正东方 canvas.rotate(90); } else if (y == 0 && x < 0) {//表示正西方 canvas.rotate(270); } else { //根据x y轴的磁场强度来计算布局的旋转角度,用三角函数计算旋转角度 if (y >= 0) { canvas.rotate((float) (Math.tanh(x / y) * 90)); } else { canvas.rotate((float) (Math.tanh(x / y) * 180)); } } //绘制指针 canvas.drawBitmap(pointer, -pointer.getWidth() / 2, -pointer.getHeight() / 2, new Paint()); } } }
二、之后在activity_magnetic_sensor.xml中引入自定义View
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:gravity="center" tools:context=".MagneticSensorActivity"> <com.example.alertdialog.custom.PointerView android:id="@+id/pointerView" android:layout_width="300dp" android:layout_height="300dp" /> </LinearLayout>
效果如图所示: