天天看點

android重力傳感器橫豎反,Android重力傳感器--随重力旋轉的圖示

相機拍攝都有橫屏拍攝和豎屏拍攝,橫豎屏切換,圖示也會跟着重力方向旋轉,于是也做了一個相機旋轉效果。

代碼在這裡面

啥也不說了,先上效果圖,gif大小限制,隻截取了一小段:

android重力傳感器橫豎反,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/-1

private int curRotateCode = 0;

//記錄目前的角度,每次旋轉從此處開始

private int curAngle = 0;

//需要操作旋轉的集合

private ArrayList views = new ArrayList<>();

public RotateSensorUtil(Context context, ArrayList 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) {

}

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

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 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) {

}

}