自定义重力布局

看到手机自带的相机在侧过来时上面的组件会跟着旋转,很好奇,在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;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值