Android使用重力传感器实现随重力旋转的图标

龙旋

共 6225字,需浏览 13分钟

 ·

2021-08-27 19:34

相机拍摄都有横屏拍摄和竖屏拍摄,横竖屏切换,图标也会跟着重力方向旋转,于是也做了一个相机旋转效果。

啥也不说了,先上效果图,gif大小限制,只截取了一小段:


在Android平台中,传感器框架通常是使用一个标准的三维坐标系去表示一个值的。以方向传感器为例,确定一个方向当然也需要一个三维坐标,三个方向值就是一个长度为3的float数组。


旋转工具类:

根据重力传感器的监听,获取X、Y方向上分量计算数值角度。

为了不实时旋转,定义4个方向范围,对应角度分别为0,90,

180,270度,遍历view作属性动画。

import android.animation.ObjectAnimator;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.view.View;import java.util.ArrayList;
public class RotateSensorUtil implements SensorEventListener{ private Context context; private SensorManager sensorManager; //默认旋转角度code,分别为 0,1/2,3,4/-1 private int curRotateCode = 0; //记录当前的角度,每次旋转从此处开始 private int curAngle = 0; //需要操作旋转的集合 private ArrayList<View> views = new ArrayList<>();
public RotateSensorUtil(Context context, ArrayList<View> views){
this.context = context; this.views = views; sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); //通过传感器管理器获取重力加速度传感器 sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL); }
@Override public void onSensorChanged(SensorEvent event) { if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){ return; }
float[] values = event.values; float ax = values[0]; float ay = values[1];

double g = Math.sqrt(ax * ax + ay * ay); double cos = ay / g; if (cos > 1) { cos = 1; } else if (cos < -1) { cos = -1; } double rad = Math.acos(cos); if (ax < 0) { rad = 2 * Math.PI - rad; }
int uiRot = ((Activity)context).getWindowManager().getDefaultDisplay().getRotation(); double uiRad = Math.PI / 2 * uiRot; rad -= uiRad;
checkBundray((int) rad); }
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/** * 旋转检测 * @param rotateCode */ private void checkBundray(int rotateCode){ if(rotateCode == 2) rotateCode = 1; if(rotateCode == -1) rotateCode = 4; int angle = 0;
switch (rotateCode){ case 0: angle = 0; break; case 1: angle = 90; break; case 3: angle = 180; break; case 4: angle = 270; break; }
if(rotateCode == curRotateCode){
}else{ valueRotateAnim(angle); curAngle = angle; curRotateCode = rotateCode; } }
private void valueRotateAnim(int angle){ //特别处理从270-0度的反向旋转 if(curAngle == 270){ angle = 360; } for(int i=0;i<views.size();i++){ startRotateAnim(views.get(i),300,curAngle,angle); } }
public void unregisterSensor(){ sensorManager.unregisterListener(this); }
public void startRotateAnim(View view,long time,int fromAngle,float toAngle){ ObjectAnimator animRotate = ObjectAnimator.ofFloat(view,"rotation",fromAngle,toAngle); animRotate.setDuration(time); animRotate.start(); }
}

MainActivity调用,传递所有要旋转图标,并调用相机。
import android.graphics.SurfaceTexture;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.TextureView;import android.view.View;import android.view.WindowManager;import android.widget.ImageView;import java.util.ArrayList;import butterknife.Bind;import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener { @Bind(R.id.textureview) TextureView textureview; @Bind(R.id.iv_close) ImageView ivClose; @Bind(R.id.more) ImageView more; @Bind(R.id.iv_switch) ImageView ivSwitch; @Bind(R.id.iv_pic) ImageView ivPic; @Bind(R.id.iv_beauty) ImageView ivBeauty; @Bind(R.id.iv_face) ImageView ivFace; @Bind(R.id.iv_filter) ImageView ivFilter; private TextureView textureView; private OpenCamera openCamera; private RotateSensorUtil sensorUtil; private ArrayList<View> rotateViews = new ArrayList<>();
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); ButterKnife.bind(this);
openCamera(); addViews(); startAnim(); }
private void startAnim() { sensorUtil = new RotateSensorUtil(this,rotateViews); }
private void addViews(){ rotateViews.add(ivClose); rotateViews.add(more); rotateViews.add(ivSwitch); rotateViews.add(ivPic); rotateViews.add(ivBeauty); rotateViews.add(ivFace); rotateViews.add(ivFilter); }
private void openCamera(){ textureView = (TextureView) findViewById(R.id.textureview); openCamera = new OpenCamera(getApplicationContext(), textureView);
openCamera.startCameraThread();
if (!textureView.isAvailable()) { textureView.setSurfaceTextureListener(this); } else { openCamera.startPreview(); } }
@Override protected void onDestroy() { super.onDestroy();
sensorUtil.unregisterSensor(); }
@Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { openCamera.setupCamera(width, height); //设置相机参数,回调的是textureview的宽高 openCamera.openCamera(); }
@Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; }
@Override public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}}

源码地址:
https://github.com/18380438200/GravitySensor

到这里就结束啦。
浏览 53
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报