悬浮球踩过的坑

公司的SDK要写一个登录界面,里面涉及到悬浮球,但是不能申请权限。起初想到的方案是利用游戏的一个Activity,通过下面代码找到容器view

View root = activity.findViewById(android.R.id.content);

然后再把悬浮球View添加进去

        View root = activity.findViewById(android.R.id.content);        if (root instanceof FrameLayout) {            FrameLayout content = (FrameLayout) root;            View viewById = content.findViewById(R.id.float_ball_icon);            if (viewById != null) {                return;            }            floatView = View.inflate(gameActivity, R.layout.view_float_ball, null);            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);            ImageView floatBallIcon = floatView.findViewById(R.id.float_ball_icon);                      params.gravity = Gravity.START;            params.topMargin = 100;            ValueAnimator animator = ValueAnimator.ofFloat(0, -UIUtils.getUIUtils().getWidth(43)).setDuration(500);            animator.setInterpolator(new LinearInterpolator());            animator.addUpdateListener(animation -> {                floatView.setX((Float) animation.getAnimatedValue());                floatView.bringToFront();            });            animator.start();            floatView.setLayoutParams(params);            floatView.bringToFront();            content.addView(floatView);        }

整体代码就是上面的,在本地跑没什么事,但是入到游戏里面发现悬浮球移动一下就消失了,后来找到原因是游戏的surfaceView会挡住,解决方法: floatView.bringToFront(); View的这个方法,在每次移动的时候都得加这行代码,保证这个View在最前面。

但是还是会有问题,就是移动的时候有时会有穿墙的效果出现。这样放到游戏里面肯定不会

后来经过思考:第二种实现应用内悬浮球的方法popwindow,经过实验果不其然比上面方法好多了,操作还简单。

主要方法:代码如下

 public FloatPopup(Context context) {        //记录当前悬浮按钮显示位置        View floatView = View.inflate(gameActivity, R.layout.view_float_ball, null);        pointView = floatView.findViewById(R.id.float_ball_point);        pointView.setVisibility(View.GONE);        ImageView floatBallIcon = floatView.findViewById(R.id.float_ball_icon);        setContentView(floatView);        setWidth(size);        setHeight(size);        setFocusable(false);        setClippingEnabled(false);        setBackgroundDrawable(new ColorDrawable(0x00000000));        setOutsideTouchable(false);                setTouchInterceptor(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                x = event.getRawX();                y = event.getRawY();                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        downX = event.getRawX();                        downY = event.getRawY();                        isClickState = true;                        break;                    case MotionEvent.ACTION_MOVE:                        if (Math.abs(x - downX) < clickLimitValue && Math.abs(y - downY) < clickLimitValue && isClickState) {                            isClickState = true;                        } else {                            isClickState = false;                            float offX = event.getRawX() - downX;                            float offY = event.getRawY() - downY;                            Log.e("floatball", "offX: " + offX + " offY:" + offY);                            update((int) (lastX + offX), (int) (offY + lastY));                        }                        break;                    case MotionEvent.ACTION_UP:                        if (x - downX < clickLimitValue && isClickState) {                            getContentView().performClick();                            break;                        }                        if (x < screenWidth / 2.f) {                            showX = 0;                            showY = lastY + event.getRawY() - downY;                        } else {                            showX = screenWidth - size;                            showY = lastY + event.getRawY() - downY;                        }                        if (showY <= 0) {                            showY = 0;                        } else if (showY >= screenHeight) {                            showY = screenHeight - size;                        }                        update((int) showX, (int) showY);                        lastX = showX;                        lastY = showY;                        v.removeCallbacks(runnable);                        v.postDelayed(runnable, 300);                        break;                }                return true;            }        });    }

这之间也碰到几个问题:

1:popwindow不能移动到屏幕外 setClippingEnabled(false);加入这行代码

2:拖拽popwindows的时候,位移处理,这里就有点小技巧,就是利用初始位置+移动偏移位置就可以完美解决。

3:还有就是旋转屏幕的时候popwindow显示不出来问题,这就要监听游戏activity的生命周期,然后做相应的重建操作

4:有时游戏界面是固定方向的,但是切换字体的时候出会让activity重建,这个时候如果我们监听了activity生命周期,在onResume的时候进行重建,这时你会发现popwindwo重建不了。解决方法:利用handler发送一个延时消息。完美解决。

更多相关文章

  1. Android开发 华为手机读取相册闪退问题
  2. android greenDao SQLite数据库操作工具类
  3. Android中的位运算的例子(一)
  4. Fragment封装切换
  5. 编写高效Android代码
  6. android email 邮件转发 附件不能转发问题的解决
  7. android中onClick事件的实现
  8. [Android实例] android登录Web以及登录保持,cookie管理相关
  9. Android(安卓)Audio代码分析=Audio Strategy

随机推荐

  1. android之WakeLock机制浅析
  2. Android层次化安全架构及核心组件概览
  3. Android版本演进史
  4. Android快速开发框架-------afinal
  5. Android(安卓)App 获取root权限后,执行she
  6. 安卓开发日记--2017.10.10
  7. 引用Android(安卓)Design包出现的错误
  8. Android开源库集锦 + Android场景桌面(一
  9. 关于android的中文文档
  10. android SDK包引用了java SDK哪些包