悬浮窗

程序员 2024-10-5 15:11:56 51 0 来自 中国
一、原理

1、添加独立的View

我们在APP中想不依靠Activity中的布局添加View时,可以通过WindowManager.addView()的方式,创建一个window,并体现添加的View。
2、Window可分为三类

应用window:一样寻常位于最底层,对应一个Activity;
子window:不能单独存在,须要附属在父window上,如Dialog;
体系window:一样寻常位于最顶层,不会被其他window遮住,如Toast。
二、悬浮窗

1、查抄权限

// 查抄悬浮窗Settings.canDrawOverlays(mContext)// 跳转到悬浮窗设置页面activity.startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,                Uri.parse("package:" + activity.getPackageName())), requestCode);2、添加悬浮窗

此处须要注意的是flag对于悬浮窗的影响:
FLAG_NOT_TOUCH_MODAL: 悬浮窗外部可相应变乱
FLAG_NOT_FOCUSABLE : 不处置惩罚体系按钮变乱
FLAG_LAYOUT_NO_LIMITS: 悬浮窗可以延伸到屏幕外
if (Settings.canDrawOverlays(mContext)) {    // 获取WindowManager服务    mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);    mLayoutParams = new WindowManager.LayoutParams();    // 设置LayoutParam    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;    } else {        mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;    }    // 悬浮窗外部可相应变乱    mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |            // 不处置惩罚体系按钮变乱            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |            // 悬浮窗可以延伸到屏幕外            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;    mLayoutParams.format = PixelFormat.RGBA_8888;    mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;    mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;    mLayoutParams.gravity = Gravity.TOP | Gravity.START;    mLayoutParams.x = 0;    mLayoutParams.y = 300;    // 将悬浮窗控件添加到WindowManager    mWindowManager.addView(mRootView, mLayoutParams);}// 移除悬浮窗try {    mWindowManager.removeView(mRootView);} catch (Exception e) {    //nothing}3、相应点击变乱

// 可以给view直接设置mRootView.setOnClickListener(onClickListener);4、拖动

起首, 在ACTION_DOWN中记载当前的x,y位置;
然后, 在ACTION_MOVE中判定滑动隔断,如果触发了滑动,算出滑动后的x,y位置,通过updateViewLayout举行更新;
末了, 在ACTION_UP中处置惩罚贴边,点击等逻辑。
// 拖动可以给view设置时间监听if (canDrag) {    mRootView.setOnTouchListener(new EFWindowOnTouchListener());}private class EFWindowOnTouchListener implements View.OnTouchListener {        private boolean isMoved;        private int oX;        private int oY;        private int x;        private int y;        @Override        public boolean onTouch(View view, MotionEvent event) {            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    // 初始化滑动的标记                    isMoved = false;                    oX = (int) event.getRawX();                    oY = (int) event.getRawY();                    x = (int) event.getRawX();                    y = (int) event.getRawY();                    break;                case MotionEvent.ACTION_MOVE:                    int nowX = (int) event.getRawX();                    int nowY = (int) event.getRawY();                    int movedX = nowX - x;                    int movedY = nowY - y;                    x = nowX;                    y = nowY;                    // 如果没有触发滑动,则举行滑动判定                    if (!isMoved && (Math.abs(oX - x) > mMinScrollDistance || Math.abs(oY - y) > mMinScrollDistance)) {                        isMoved = true;                    }                    // 拖动中不能用贴边盘算                    mLayoutParams.x = getRealX(mLayoutParams.x + movedX, false, false);                    mLayoutParams.y = getRealY(mLayoutParams.y + movedY, false);                    mWindowManager.updateViewLayout(view, mLayoutParams);                    break;                case MotionEvent.ACTION_UP:                    if (mIsSticky) {                        int viewWidth = view.getMeasuredWidth();                        int screenWidth = ScreenUtils.getScreenWidth(mContext);                        // 贴边尽头只有左、右两种状态                        if ((mLayoutParams.x + viewWidth / 2) > screenWidth / 2) {                            if (mOnPositionListener != null) {                                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);                            }                            mLayoutParams.x = screenWidth - viewWidth - mXEdgeSize;                        } else {                            if (mOnPositionListener != null) {                                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);                            }                            mLayoutParams.x = mXEdgeSize;                        }                        mWindowManager.updateViewLayout(view, mLayoutParams);                    }                    // 处置惩罚移动后还会相应点击变乱的环境                    if (isMoved) {                        isMoved = false;                        return true;                    }                    break;                default:                    break;            }            return false;        }    }5、横竖屏切换适配

监听到屏幕厘革后,由于屏幕的长宽发生了厘革,重新盘算当前的x,y,并举行更新。
// 添加屏幕厘革监听DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {    @Override    public void onDisplayAdded(int displayId) {    }    @Override    public void onDisplayRemoved(int displayId) {    }    @Override    public void onDisplayChanged(int displayId) {        // 监听到屏幕发生厘革        if (mLayoutParams != null && mWindowManager != null                && mRootView != null && mRootView.isAttachedToWindow()) {            mLayoutParams.x = getRealX(mLayoutParams.x, false, true);            mLayoutParams.y = getRealY(mLayoutParams.y, false);            mWindowManager.updateViewLayout(mRootView, mLayoutParams);        }    }}, new Handler(Looper.getMainLooper()));6、贴边,缩进等处置惩罚

private int getRealX(int xPosition, boolean isInit, boolean considerSticky) {    if (isInit) {        // 此时view还没有触发测量,主动测量一次        getRootView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);    }    int viewWidth = getRootView().getMeasuredWidth();    int screenWidth = ScreenUtils.getScreenWidth(mContext);    int screenHeight = ScreenUtils.getScreenHeight(mContext);    // 部分手机,如:vivo R9s,横竖屏切换,获取的值不会发生厘革,此处做一个适配    screenWidth = isHorizontalScreen(mContext) ? Math.max(screenWidth, screenHeight) : Math.min(screenWidth, screenHeight);    // 贴边初始只有左和右,没有中心态    if (considerSticky && mIsSticky) {        if ((xPosition + viewWidth / 2) > screenWidth / 2) {// 处置惩罚缩进            if (mOnPositionListener != null) {                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);            }            // 贴右边体现,真实坐标为(屏幕宽度 - view的宽度 - x边距)            return screenWidth - viewWidth - mXEdgeSize;        } else {            if (mOnPositionListener != null) {                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);            }            // 贴左边体现,真实坐标为(左出发点 + x边距),左边的出发点为0。            return mXEdgeSize;        }    } else {        if (xPosition > (screenWidth - viewWidth - mXEdgeSize)) {            if (mOnPositionListener != null) {                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);            }            // 当前位置已经超过允许的右边距,返回最右边距            return screenWidth - viewWidth - mXEdgeSize;        } else if (xPosition < mXEdgeSize) {            if (mOnPositionListener != null) {                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);            }            // 当前位置小于允许的左边距,返回最左边距            return mXEdgeSize;        } else {            if (mOnPositionListener != null) {                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_MIDDLE);            }            // 由于不吸边,以是展示真实位置            return xPosition;        }    }}private int getRealY(int yPosition, boolean isInit) {    // 此时view还没有触发测量,主动测量一次    if (isInit) {        getRootView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);    }    int viewHeight = getRootView().getMeasuredHeight();    int screenWidth = ScreenUtils.getScreenWidth(mContext);    int screenHeight = ScreenUtils.getScreenHeight(mContext);    // 部分手机,如:vivo R9s,横竖屏切换,获取的值不会发生厘革,此处做一个适配    screenHeight = isHorizontalScreen(mContext) ? Math.min(screenWidth, screenHeight) : Math.max(screenWidth, screenHeight);    if (yPosition > (screenHeight - viewHeight - mYBottomEdgeSize)) {        // 当前位置已经超过允许的下边距,返回最下边距        return screenHeight - viewHeight - mYBottomEdgeSize;    } else if (yPosition < mYTopEdgeSize) {        // 当前位置小于允许的上边距,返回最上边距        return mYTopEdgeSize;    } else {        // 展示真实位置        return yPosition;    }}private boolean isHorizontalScreen(Context context) {    int angle = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();    //屏幕旋转90°或270°,体现横屏    return angle == Surface.ROTATION_90 || angle == Surface.ROTATION_270;}三、注意

部分场景须要点击回到当前的Activity,可以参考如下代码:
// 方法一:跳转到app展示的上一个页面public void onClick(View v) {    Intent intent = BaseApplication.getGlobalContext().getPackageManager().getLaunchIntentForPackage(BaseApplication.getGlobalContext().getPackageName());    BaseApplication.getGlobalContext().startActivity(intent);}// 方法二:当地缓存页面,判定登录状态跳转不同的页面public void onClick(View v) {    // 注意,这里的跳转没有参数通报,在一些activity的onNewIntent中会对intent举行再次分析    // 因此,须要判定是否是从悬浮窗跳已往的,举行拦截,防止出现非常    // 也可以将准确的参数通报已往,本钱较高,用作备选项    // FLAG_ACTIVITY_SINGLE_TOP,如果当前activity已经在栈顶,不再创建,直接跳转    // FLAG_ACTIVITY_REORDER_TO_FRONT,如果activity已经创建了,如:ABCD,跳转到B,不会重新创建,且变为ACDB    if (ACCOUNT_CONTROLLER.hasLogin()) {        if (mCurrentActivity != null) {            // 正常环境都不是null,除非长时间被体系采取了            Intent targetIntent = new Intent(BaseApplication.getGlobalContext(), mCurrentActivity.getClass());            targetIntent.putExtra(SpName.INTENT_FROM, FROM_EFWINDOW);            targetIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);            mCurrentActivity.startActivity(targetIntent);        } else {            // 跳转首页,然后通过规复接口举行再次跳转            Intent targetIntent = new Intent(BaseApplication.getGlobalContext(), HomeActivity.class);            targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);            targetIntent.putExtra(SpName.INTENT_FROM, FROM_EFWINDOW);            BaseApplication.getGlobalContext().startActivity(targetIntent);        }    } else {        // 登录信息失效了        Intent targetIntent = new Intent(BaseApplication.getGlobalContext(), LoginActivity.class);        targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);        targetIntent.putExtra(SpName.INTENT_FROM, FROM_EFWINDOW);        BaseApplication.getGlobalContext().startActivity(targetIntent);        ToastUtil.showMessage("登录信息失效,请重新登录");    }}四、悬浮窗代码

//try {//    if (mEfWindow == null) {//        View view = LayoutInflater.from(BaseApplication.getGlobalContext()).inflate(R.layout.layout_edj_floating_window, null);//        mEfWindow = new EFWindow.Builder(BaseApplication.getGlobalContext())//                .view(view)//                .yPosition(ScreenUtils.getScreenHeight(BaseApplication.getGlobalContext()) / 3)//                .isSticky(true)//                .canDrag(true)//                .xEdgeSize(-UIUtils.dp2px(BaseApplication.getGlobalContext(), 20))//                .onClickListener(this)//                .build();//    }//    mEfWindow.show();//} catch (Exception e) {//    e.printStackTrace();//}public class EFWindow {    private final int mMinScrollDistance;    private WindowManager mWindowManager;    private WindowManager.LayoutParams mLayoutParams;    private final View mRootView;    private boolean mIsShow;    private boolean mIsSticky;    private int mXEdgeSize;    private int mYTopEdgeSize;    private int mYBottomEdgeSize;    private OnPositionListener mOnPositionListener;    private final Context mContext;    @RequiresApi(api = Build.VERSION_CODES.M)    private EFWindow(Builder builder) {        // 赋值        mContext = builder.mContext;        mMinScrollDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();        mIsSticky = builder.mIsSticky;        mXEdgeSize = builder.mXEdgeSize;        mYTopEdgeSize = builder.mYTopEdgeSize;        mYBottomEdgeSize = builder.mYBottomEdgeSize;        mOnPositionListener = builder.mOnPositionListener;        mRootView = builder.mRootView;        boolean canDrag = builder.mCanDrag;        int xPosition = builder.mXPosition;        int yPosition = builder.mYPosition;        View.OnClickListener onClickListener = builder.mOnClickListener;        // 添加屏幕厘革监听        DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);        displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {            @Override            public void onDisplayAdded(int displayId) {            }            @Override            public void onDisplayRemoved(int displayId) {            }            @Override            public void onDisplayChanged(int displayId) {                // 监听到屏幕发生厘革                if (mLayoutParams != null && mWindowManager != null                        && mRootView != null && mRootView.isAttachedToWindow()) {                    mLayoutParams.x = getRealX(mLayoutParams.x, false, true);                    mLayoutParams.y = getRealY(mLayoutParams.y, false);                    mWindowManager.updateViewLayout(mRootView, mLayoutParams);                }            }        }, new Handler(Looper.getMainLooper()));        if (Settings.canDrawOverlays(mContext)) {            // 获取WindowManager服务            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);            if (canDrag) {                mRootView.setOnTouchListener(new EFWindowOnTouchListener());            }            mRootView.setOnClickListener(onClickListener);            mLayoutParams = new WindowManager.LayoutParams();            // 设置LayoutParam            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {                mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;            } else {                mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;            }            // 悬浮窗外部可相应变乱            mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |                    // 不处置惩罚体系按钮变乱                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |                    // 悬浮窗可以延伸到屏幕外                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;            mLayoutParams.format = PixelFormat.RGBA_8888;            mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;            mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;            mLayoutParams.gravity = Gravity.TOP | Gravity.START;            mLayoutParams.x = getRealX(xPosition, true, true);            mLayoutParams.y = getRealY(yPosition, true);        }    }    private int getRealX(int xPosition, boolean isInit, boolean considerSticky) {        if (isInit) {            // 此时view还没有触发测量,主动测量一次            getRootView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);        }        int viewWidth = getRootView().getMeasuredWidth();        int screenWidth = ScreenUtils.getScreenWidth(mContext);        int screenHeight = ScreenUtils.getScreenHeight(mContext);        // 部分手机,如:vivo R9s,横竖屏切换,获取的值不会发生厘革,此处做一个适配        screenWidth = isHorizontalScreen(mContext) ? Math.max(screenWidth, screenHeight) : Math.min(screenWidth, screenHeight);        // 贴边初始只有左和右,没有中心态        if (considerSticky && mIsSticky) {            if ((xPosition + viewWidth / 2) > screenWidth / 2) {// 处置惩罚缩进                if (mOnPositionListener != null) {                    mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);                }                // 贴右边体现,真实坐标为(屏幕宽度 - view的宽度 - x边距)                return screenWidth - viewWidth - mXEdgeSize;            } else {                if (mOnPositionListener != null) {                    mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);                }                // 贴左边体现,真实坐标为(左出发点 + x边距),左边的出发点为0。                return mXEdgeSize;            }        } else {            if (xPosition > (screenWidth - viewWidth - mXEdgeSize)) {                if (mOnPositionListener != null) {                    mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);                }                // 当前位置已经超过允许的右边距,返回最右边距                return screenWidth - viewWidth - mXEdgeSize;            } else if (xPosition < mXEdgeSize) {                if (mOnPositionListener != null) {                    mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);                }                // 当前位置小于允许的左边距,返回最左边距                return mXEdgeSize;            } else {                if (mOnPositionListener != null) {                    mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_MIDDLE);                }                // 由于不吸边,以是展示真实位置                return xPosition;            }        }    }    private int getRealY(int yPosition, boolean isInit) {        // 此时view还没有触发测量,主动测量一次        if (isInit) {            getRootView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);        }        int viewHeight = getRootView().getMeasuredHeight();        int screenWidth = ScreenUtils.getScreenWidth(mContext);        int screenHeight = ScreenUtils.getScreenHeight(mContext);        // 部分手机,如:vivo R9s,横竖屏切换,获取的值不会发生厘革,此处做一个适配        screenHeight = isHorizontalScreen(mContext) ? Math.min(screenWidth, screenHeight) : Math.max(screenWidth, screenHeight);        if (yPosition > (screenHeight - viewHeight - mYBottomEdgeSize)) {            // 当前位置已经超过允许的下边距,返回最下边距            return screenHeight - viewHeight - mYBottomEdgeSize;        } else if (yPosition < mYTopEdgeSize) {            // 当前位置小于允许的上边距,返回最上边距            return mYTopEdgeSize;        } else {            // 展示真实位置            return yPosition;        }    }    public View getRootView() {        return mRootView;    }    public boolean isShow() {        return mIsShow;    }    public void show() {        mIsShow = true;        // 先实行移除        try {            mLayoutParams.x = getRealX(mLayoutParams.x, false, true);            mLayoutParams.y = getRealY(mLayoutParams.y, false);            mWindowManager.removeView(mRootView);        } catch (Exception e) {            //nothing        }        // 将悬浮窗控件添加到WindowManager        mWindowManager.addView(mRootView, mLayoutParams);    }    public void dismiss() {        // 实行移除        try {            mWindowManager.removeView(mRootView);        } catch (Exception e) {            //nothing        }        mIsShow = false;    }    private class EFWindowOnTouchListener implements View.OnTouchListener {        private boolean isMoved;        private int oX;        private int oY;        private int x;        private int y;        @Override        public boolean onTouch(View view, MotionEvent event) {            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    // 初始化滑动的标记                    isMoved = false;                    oX = (int) event.getRawX();                    oY = (int) event.getRawY();                    x = (int) event.getRawX();                    y = (int) event.getRawY();                    break;                case MotionEvent.ACTION_MOVE:                    int nowX = (int) event.getRawX();                    int nowY = (int) event.getRawY();                    int movedX = nowX - x;                    int movedY = nowY - y;                    x = nowX;                    y = nowY;                    // 如果没有触发滑动,则举行滑动判定                    if (!isMoved && (Math.abs(oX - x) > mMinScrollDistance || Math.abs(oY - y) > mMinScrollDistance)) {                        isMoved = true;                    }                    // 拖动中不能用贴边盘算                    mLayoutParams.x = getRealX(mLayoutParams.x + movedX, false, false);                    mLayoutParams.y = getRealY(mLayoutParams.y + movedY, false);                    mWindowManager.updateViewLayout(view, mLayoutParams);                    break;                case MotionEvent.ACTION_UP:                    if (mIsSticky) {                        int viewWidth = view.getMeasuredWidth();                        int screenWidth = ScreenUtils.getScreenWidth(mContext);                        // 贴边尽头只有左、右两种状态                        if ((mLayoutParams.x + viewWidth / 2) > screenWidth / 2) {                            if (mOnPositionListener != null) {                                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_RIGHT);                            }                            mLayoutParams.x = screenWidth - viewWidth - mXEdgeSize;                        } else {                            if (mOnPositionListener != null) {                                mOnPositionListener.onPositionChanged(OnPositionListener.POSITION_LEFT);                            }                            mLayoutParams.x = mXEdgeSize;                        }                        mWindowManager.updateViewLayout(view, mLayoutParams);                    }                    // 处置惩罚移动后还会相应点击变乱的环境                    if (isMoved) {                        isMoved = false;                        return true;                    }                    break;                default:                    break;            }            return false;        }    }    public static class Builder {        private final Context mContext;        private View mRootView;        private int mXPosition;        private int mYPosition;        private boolean mCanDrag;        private boolean mIsSticky;        private int mXEdgeSize;        private int mYTopEdgeSize;        private int mYBottomEdgeSize;        private View.OnClickListener mOnClickListener;        private OnPositionListener mOnPositionListener;        public Builder(Context context) {            mContext = context;        }        public Builder onPositionListener(OnPositionListener onPositionListener) {            mOnPositionListener = onPositionListener;            return this;        }        public Builder onClickListener(View.OnClickListener onClickListener) {            mOnClickListener = onClickListener;            return this;        }        public Builder xPosition(int xPosition) {            mXPosition = xPosition;            return this;        }        public Builder yPosition(int yPosition) {            mYPosition = yPosition;            return this;        }        public Builder view(View view) {            mRootView = view;            return this;        }        public Builder canDrag(boolean canDrag) {            mCanDrag = canDrag;            return this;        }        public Builder isSticky(boolean isSticky) {            mIsSticky = isSticky;            return this;        }        public Builder xEdgeSize(int xEdgeSize) {            mXEdgeSize = xEdgeSize;            return this;        }        public Builder yTopEdgeSize(int yTopEdgeSize) {            mYTopEdgeSize = yTopEdgeSize;            return this;        }        public Builder yBottomEdgeSize(int yBottomEdgeSize) {            mYBottomEdgeSize = yBottomEdgeSize;            return this;        }        public Builder view(int viewRes) throws Exception {            if (mContext == null) {                throw new Exception("EFWindow:请传入准确的context.");            }            mRootView = LayoutInflater.from(mContext).inflate(viewRes, null);            return this;        }        @RequiresApi(api = Build.VERSION_CODES.M)        public EFWindow build() throws Exception {            if (mContext == null) {                throw new Exception("EFWindow:请传入准确的context.");            }            if (mRootView == null) {                throw new Exception("EFWindow:请先设置Window布局.");            }            return new EFWindow(this);        }    }    public interface OnPositionListener {        int POSITION_LEFT = 0;        int POSITION_MIDDLE = 1;        int POSITION_RIGHT = 2;        void onPositionChanged(int positionStatus);    }    private boolean isHorizontalScreen(Context context) {        int angle = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();        //屏幕旋转90°或270°,体现横屏        return angle == Surface.ROTATION_90 || angle == Surface.ROTATION_270;    }}
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-21 21:20, Processed in 0.217684 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表