Android使用重力传感器实现随重力旋转的图标
龙旋
共 6225字,需浏览 13分钟
·
2021-08-27 19:34
在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();
}
}
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) {
}
}
评论