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

在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/-1private 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);}@Overridepublic 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);}@Overridepublic 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();}}
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<>();@Overrideprotected 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();}}@Overrideprotected void onDestroy() {super.onDestroy();sensorUtil.unregisterSensor();}@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {openCamera.setupCamera(width, height); //设置相机参数,回调的是textureview的宽高openCamera.openCamera();}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {return false;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surface) {}}
评论
