相機拍攝都有橫屏拍攝和豎屏拍攝,橫豎屏切換,圖示也會跟着重力方向旋轉,于是也做了一個相機旋轉效果。
代碼在這裡面
啥也不說了,先上效果圖,gif大小限制,隻截取了一小段:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI5YTOyAzN0MTZyQ2MvwFcvwVbvNmL1h2cuFWaq5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
示範
在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) {
}
}