看到手机自带的相机在侧过来时上面的组件会跟着旋转,很好奇,在activity方向固定的情况下怎么做到的。
参考了这篇文章:Android实现屏幕旋转方法总结的第4个方法
使用时请注意,我的activity设置的screenOrentation 以使activity不会onCreate
上代码:
import android.content.Context;
import android.util.AttributeSet;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;
public class GravityLayout extends RelativeLayout {
private int mDirection = -1;
public GravityLayout(Context context) {
super(context);
init();
}
public GravityLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GravityLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
startOrientationChangeListener();
}
private void startOrientationChangeListener() {
OrientationEventListener mOrientationListener = new OrientationEventListener(getContext()) {
@Override
public void onOrientationChanged(int rotation) {
if (mDirection == -1) {
initDirect(rotation);
// 初始化时view为protrait要纠正过来
if(mDirection == Direction.RIGHT_LANDSCAPE) {
orientationChanged(getAnim(Direction.END, Direction.RIGHT_LANDSCAPE));
}else if(mDirection == Direction.LEFT_LANDSCAPE) {
orientationChanged(getAnim(Direction.PORTRAIT, Direction.LEFT_LANDSCAPE));
}else if(mDirection == Direction.CONVERT_PORTRAIT) {
orientationChanged(getAnim(Direction.PORTRAIT, Direction.LEFT_LANDSCAPE));
orientationChanged(getAnim(Direction.LEFT_LANDSCAPE, Direction.CONVERT_PORTRAIT));
}
}
if (mDirection != Direction.PORTRAIT &&
(((rotation >= 0) && (rotation <= 15)) ||
((rotation >= 344) && (rotation <= 359)))) {//PORTRAIT
if (mDirection == Direction.LEFT_LANDSCAPE) {
orientationChanged(getAnim(Direction.LEFT_LANDSCAPE, Direction.PORTRAIT));
} else { //if(mDirection == Direction.RIGHT_LANDSCAPE) {
orientationChanged(getAnim(Direction.RIGHT_LANDSCAPE, Direction.END));
}
mDirection = Direction.PORTRAIT;
} else if (mDirection != Direction.RIGHT_LANDSCAPE &&
(rotation >= 75) && ((rotation <= 105))) { // RIGHT_LANDSCAPE
if (mDirection == Direction.PORTRAIT) {
orientationChanged(getAnim(Direction.END, Direction.RIGHT_LANDSCAPE));
} else {
orientationChanged(getAnim(Direction.CONVERT_PORTRAIT, Direction.RIGHT_LANDSCAPE));
}
mDirection = Direction.RIGHT_LANDSCAPE;
} else if (mDirection != Direction.CONVERT_PORTRAIT &&
(rotation >= 165) && (rotation <= 195)) { // CONVERT_PORTRAIT
if (mDirection == Direction.RIGHT_LANDSCAPE) {
orientationChanged(getAnim(Direction.RIGHT_LANDSCAPE, Direction.CONVERT_PORTRAIT));
} else {
orientationChanged(getAnim(Direction.LEFT_LANDSCAPE, Direction.CONVERT_PORTRAIT));
}
mDirection = Direction.CONVERT_PORTRAIT;
} else if (mDirection != Direction.LEFT_LANDSCAPE &&
(rotation >= 255) && (rotation <= 285)) { // LEFT_LANDSCAPE
if (mDirection == Direction.CONVERT_PORTRAIT) {
orientationChanged(getAnim(Direction.CONVERT_PORTRAIT, Direction.LEFT_LANDSCAPE));
} else {
orientationChanged(getAnim(Direction.PORTRAIT, Direction.LEFT_LANDSCAPE));
}
mDirection = Direction.LEFT_LANDSCAPE;
}
}
private void initDirect(int rotation) {
if ((((rotation >= 0) && (rotation <= 15)) ||
((rotation >= 344) && (rotation <= 359)))) {//PORTRAIT
mDirection = Direction.PORTRAIT;
} else if ((rotation >= 75) && ((rotation <= 105))) { // RIGHT_LANDSCAPE
mDirection = Direction.RIGHT_LANDSCAPE;
} else if ((rotation >= 165) && (rotation <= 195)) { // CONVERT_PORTRAIT
mDirection = Direction.CONVERT_PORTRAIT;
} else if ((rotation >= 255) && (rotation <= 285)) { // LEFT_LANDSCAPE
mDirection = Direction.LEFT_LANDSCAPE;
}
}
};
mOrientationListener.enable();
}
private void orientationChanged(Animation anim) {
int count = getChildCount();
for(int i = 0; i < count; i++) {
View view = getChildAt(i);
view.startAnimation(anim);
}
}
private RotateAnimation getAnim(int from, int to) {
RotateAnimation anim = new RotateAnimation(from, to,
Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);
anim.setDuration(400);
anim.setFillAfter(true);
return anim;
}
class Direction{
public static final int PORTRAIT = 0;
public static final int LEFT_LANDSCAPE = 90;
public static final int CONVERT_PORTRAIT = 180;
public static final int RIGHT_LANDSCAPE = 270;
public static final int END = 359;
}
}