Android 方向传感器的简单使用

方向传感器基本是Android手机必备功能,所有这个demo基本都可以使用。
静态效果图
界面一个ImageView(蓝色条) 下面是自己画的圆和线(最开始没去找图,懒)

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/iv"
        android:layout_marginTop="60dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/sensor"
        android:contentDescription="@string/app_name" />

    <com.ui.ArrowsView
        android:id="@+id/arrows"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </com.ui.ArrowsView>

</LinearLayout>

自定义的View可以直接替换掉,蓝色条可以自己换其他图片,没有影响,下面贴Activity,无非就是通过系统服务获取传感器控制器SensorManager,注册监听,在监听器里面使用补间动画或者设置旋转setRotation。
需要注意的是使用补间动画旋转 RotateAnimation 时,在0-360 跳转间隔即△>300+时指针会多旋转方向错误,这时需要添加一个判断,当间隔过大,即跳变的时候,把 起始位置/结束位置 -360,即可。

这里写图片描述

代码如下:

package com.widget;

import com.sernortest.R;
import com.ui.ArrowsView;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

public class ArrowsViewActivity extends Activity {

    private ArrowsView arrows;
    private ImageView iv;
    private Sensor sensor;
    private SensorManager manager;

    private RotateAnimation rotate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_arrows);
        arrows = (ArrowsView) findViewById(R.id.arrows);
        iv = (ImageView) findViewById(R.id.iv);
        manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        sensor = manager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
        super.onResume();
    }

    @Override
    protected void onPause() {
        manager.unregisterListener(listener);
        super.onPause();
    }

    float predegree = -100;//起始角度
    float degree;//结束角度
    float mdg = 180;//设置旋转间隔 数值可以自行调整

/**
*
*由于我使用一个自定义view,而系统的刷新频率太快,
*所以加了判断降低刷新频率,现在是0.5s刷新
*单个ImageView的话不建议降低刷新频率,会显得卡顿,保持默认刷新即可
*/
    float dt=500;//刷新频率0.5s
    long nowT;
    long lastT = -1;
    private SensorEventListener listener = new SensorEventListener() {

        @Override
        public void onSensorChanged(SensorEvent event) {
            try {
                if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
                    degree = event.values[0];
                    arrows.setRotate(degree);

                    if (predegree == -100) {
                        predegree = degree;
                        return;
                    }

                    nowT = System.currentTimeMillis();
                    if (lastT == -1) {
                        lastT = nowT;
                        return;
                    }

                    if (dt < (nowT - lastT)) {
                        if((degree-predegree)>mdg){
                            degree = degree-360;
                        }else if((degree-predegree)<-mdg){
                            predegree = predegree-360;
                        }

                        rotate = new RotateAnimation(predegree, degree, Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 1f);
                        rotate.setDuration(300);
                        rotate.setFillAfter(true);
                        iv.startAnimation(rotate);
                        predegree = degree;
                        lastT = 0;
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // TODO Auto-generated method stub

        }
    };
}

自定义ArrowsView仅供参考

package com.ui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;

public class ArrowsView extends View {

    private float mWidth = 700;
    private float mHeight = 700;
    private float degree = 0;
    Paint mPaint , paint;

    public ArrowsView(Context context) {
        this(context, null);
    }

    public ArrowsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        paint = new Paint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension((int) mWidth, (int) mHeight);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension((int) mWidth, heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSize, (int) mHeight);
        }

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.mWidth = Math.min(getWidth(), getHeight());
        this.mHeight = Math.max(getWidth(), getHeight());

            mPaint.setAntiAlias(true);
            mPaint.setStyle(Style.STROKE);
            mPaint.setStrokeWidth(6);

            canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2 - 100, mPaint);
            mPaint.setStyle(Style.FILL);
            canvas.drawCircle(mWidth / 2, mHeight / 2, 15, mPaint);


            paint.setAntiAlias(true);
            paint.setStrokeWidth(10);

            canvas.rotate(degree, mWidth / 2, mHeight / 2);
            canvas.drawLine(mWidth / 2, mHeight / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 110, paint);
            canvas.rotate(-degree, mWidth / 2, mHeight / 2);
    }

    public void setRotate(float degree) {
        this.degree = degree;
        postInvalidate();
    }
}

Demo下载戳我

猜你喜欢

转载自blog.csdn.net/ganfanzhou/article/details/50385815