实战第14篇:方向传感器+RotateAnimation做一个指北针

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情


一、展示效果

本次实战项目,利用Android中的方向传感器,开发一个指北针app,效果如下:

视频20.gif

二、源码放送

布局中只有ImageView图片,如果还不会写,请给我评论,我一定要……告诉你。

Activity里的代码比较重要,给大家展示一下。

public class MainActivity extends Activity {

    private ImageView imageView;
    private SensorManager manager;
    private SensorListener listener = new SensorListener();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.imageView);
        // 获取管理器
        manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }
    
    // 建立回调
    private final class SensorListener implements SensorEventListener {
        private float predegree = 0;
        @Override
        public void onSensorChanged(SensorEvent event) {
            float degree = event.values[0];
            RotateAnimation animation = new RotateAnimation(predegree, degree,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            animation.setDuration(200);
            imageView.startAnimation(animation);
            predegree = -degree;
        }
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) { 
        
        }
    }
    
    @Override
    protected void onResume() {
        // 关联回调
        Sensor 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();
    }
}
复制代码

如果你读起来没有压力,那点个赞,就撤吧。

如果看不明白的,听我白话白话,点个赞,就撤吧。

三、项目解读

2.1 传感器 Sensor

传感器是一种物理装置或生物器官,能够探测、感受外界的信号。现实生活中有很多传感器,就比如下面的这个,这是一个光敏传感器。

4db118acad3a4981acd6de41330db89f.jpeg

它会感知光线强弱的变化,这也是声控灯在黑夜才亮的硬件支持,这个很常见。

同样啊,手机里也有很多传感器。在Android中传感器包括硬件信息、当前位置、加速计、陀螺仪、光感、磁场、定向、电池窗台,声压等等。

我们说的方向传感器,简称为O-sensor,O就是Orientation,它是手机里的一个小硬件模块,它可以通过地球的磁场系统,感知方位的变化,返回三轴的角度数据,方向数据的单位是角度。不用联网,有电就行,跟灯泡一样。

2.2 调用方法

昨天讲过了,要调用硬件,很复杂,但是Android SDK帮了很多忙……自己去看吧《实战第13篇:距离传感器-调用方法》。

如果要调用方向传感器的数据,和昨天说的步骤有98%相似,也是需要两步:

第一步:从SensorManager得到Sensor传感器。

不同点是,获取类型时传递参数换成Sensor.TYPE_ORIENTATION,这说明我们要用方向传感器。

第二步:给Sensor传感器注册回调。

不同点是,SensorEvent event中的参数,比昨天的复杂一些。

……
    @Override
    public void onSensorChanged(SensorEvent event) {
        // event.values[0]  方位角,手机绕着Z轴旋转的角度。0表示正北(North)。
        // event.values[1]  倾斜角,手机绕着x轴倾斜时该值会发生变化。
        // event.values[2]  滚动角,沿着Y轴的滚动角度。
    }
——
复制代码

重点说一下我们关注的传感器数据event.values

这里面values[0]表示方位角,手机绕着Z轴旋转的角度。

image.png

0表示正北(North),这就是我们今天需要的数据,这一个数据,就够我们实现指北针功能了。

其他数据比如倾斜角、滚动角也非常有意思,可以有很多应用,这需要发挥你的创造力了。

2.3 动画的控制 RotateAnimation

我们已经拿到了手机Z轴的旋转角度,也就是values[0]。每当手机旋转时,values[0]会变化,表示距离正北旋转的角度。那如何把这些343650角度数据,转变为指北针页面呢?

数据为0时,表示正北。数据为p值时,表示相对于正北偏移的角度。

如果,我们使用一种方法,让一张图片反向旋转p度,是不是它就永远指向正北了。

1.png

正好,Android有一个旋转动画RotateAnimation,用它可以实现图片角度的旋转。

来看一下它的构造方式:

RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
复制代码

各个参数的意义如下:

属性 说明
fromDegrees 起始角度值。
toDegrees 结束角度值。
pivotXType 转动点X轴的转动标准,RELATIVE_TO_SELF 以自己为标准。
pivotXValue 针对上面标准的值,取值0-1之间。
pivotYType 转动点Y轴的转动标准,RELATIVE_TO_SELF 以自己为标准。
pivotYValue 针对上面标准的值,取值0-1之间。

那么,我们就利用这个动画类,实现图片的旋转。

视频20.gif

传感器偏移多少度,我们给他反向拧回来,从视觉上看,他就不偏移了,一直指向0度的北方。

实现代码如下:

float degree = event.values[0];
RotateAnimation animation = new RotateAnimation(predegree, degree,
        Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(200);
imageView.startAnimation(animation);
复制代码

2.4 注销回调

源码中,在ActivityonPause方法中,有这么一段manager.unregisterListener(listener),这表示注销回调。你想,我们都不看手机里,你还让指北针转着给谁看,这里面有生命周期的知识

最后

上面详细说明了利用方向传感器,加上动画控制,我们实现了一个指北针。

这就是通过技术可获取的数据,加上创造性思考,形成了生活的解决方案。技术人掌握很多技术点,可以根据技术点设计成解决方案,我们可以拿着解决方案去找愿意合作的人,共同发展。这就是技术人的优势。

我是TF男孩,关注我的掘金专栏《Java转Android》。日读1000字,30天可入门安卓开发。

本文由TF男孩在掘金社区独家发布,转载请注明出处。

猜你喜欢

转载自juejin.im/post/7131505775024799775
今日推荐