• android 一直在最前面的浮动窗口效果


    今天发现一些软件可以在android 的桌面上显示一些浮动小窗口,经过一番查找,终于找到的解决方案,代码如下:

    FloatingFunc.java

    package hrxcframe.comm;

    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Rect;
    import android.test.R;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.view.WindowManager.LayoutParams;

    /**
     * 可以永远显示在android屏幕最上方的浮动菜单
     *
     * @author liujl v1.0 需要添加 <uses-permission
     *         android:name="android.permission.SYSTEM_ALERT_WINDOW"
     *         /><!--系统弹出窗口权限-->权限不然会报错
     */
    public class FloatingFunc {
        /**
         * 浮动窗口在屏幕中的x坐标
         */
        private static float x = 0;
        /**
         * 浮动窗口在屏幕中的y坐标
         */
        private static float y = 200;
        /**
         * 屏幕触摸状态,暂时未使用
         */
        private static float state = 0;
        /**
         * 鼠标触摸开始位置
         */
        private static float mTouchStartX = 0;
        /**
         * 鼠标触摸结束位置
         */
        private static float mTouchStartY = 0;
        /**
         * windows 窗口管理器
         */
        private static WindowManager wm = null;

        /**
         * 浮动显示对象
         */
        private static View floatingViewObj = null;

        /**
         * 参数设定类
         */
        public static WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        public static int TOOL_BAR_HIGH = 0;
        /**
         * 要显示在窗口最前面的对象
         */
        private static View view_obj = null;

        /**
         * 要显示在窗口最前面的方法
         *
         * @param context
         *            调用对象Context getApplicationContext()
         * @param window
         *            调用对象 Window getWindow()
         * @param floatingViewObj
         *            要显示的浮动对象 View
         */
        public static void show(Context context, Window window, View floatingViewObj) {
            // 加载xml文件中样式例子代码
            // ********************************Start**************************
            // LayoutInflater inflater =
            // LayoutInflater.from(getApplicationContext());
            // View view = inflater.inflate(R.layout.topframe, null);
            // wm =
            // (WindowManager)context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
            // 加载xml文件中样式例子代码
            // *********************************End***************************
            //
            // 关闭浮动显示对象然后再显示
            close(context);
            FloatingFunc.floatingViewObj = floatingViewObj;

            view_obj = floatingViewObj;
            Rect frame = new Rect();
            // 这一句是关键,让其在top 层显示
            // getWindow()
            window.getDecorView().getWindowVisibleDisplayFrame(frame);
            TOOL_BAR_HIGH = frame.top;

            wm = (WindowManager) context// getApplicationContext()
                    .getSystemService(Activity.WINDOW_SERVICE);
            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
                    | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
            params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | LayoutParams.FLAG_NOT_FOCUSABLE;

            // 设置悬浮窗口长宽数据
            params.width = WindowManager.LayoutParams.WRAP_CONTENT;
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            // 设定透明度
            params.alpha = 80;
            // 设定内部文字对齐方式
            params.gravity = Gravity.LEFT | Gravity.TOP;

            // 以屏幕左上角为原点,设置x、y初始值ֵ
            params.x = (int) x;
            params.y = (int) y;
            // tv = new MyTextView(TopFrame.this);
            wm.addView(floatingViewObj, params);

        }

        /**
         * 跟谁滑动移动
         *
         * @param event
         *            事件对象
         * @param view
         *            弹出对象实例(View)
         * @return
         */
        public static boolean onTouchEvent(MotionEvent event, View view) {

            // 获取相对屏幕的坐标,即以屏幕左上角为原点
            x = event.getRawX();
            y = event.getRawY() - 25; // 25是系统状态栏的高度
            Log.i("currP", "currX" + x + "====currY" + y);// 调试信息
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                state = MotionEvent.ACTION_DOWN;
                // panTime();
                // 获取相对View的坐标,即以此View左上角为原点
                mTouchStartX = event.getX();
                mTouchStartY = event.getY();
                Log.i("startP", "startX" + mTouchStartX + "====startY"
                        + mTouchStartY);// 调试信息

                break;
            case MotionEvent.ACTION_MOVE:
                state = MotionEvent.ACTION_MOVE;
                updateViewPosition(view);
                break;

            case MotionEvent.ACTION_UP:
                state = MotionEvent.ACTION_UP;
                updateViewPosition(view);
                mTouchStartX = mTouchStartY = 0;
                break;
            }
            return true;
        }

        /**
         * 关闭浮动显示对象
         */
        public static void close(Context context) {

            if (view_obj != null && view_obj.isShown()) {
                WindowManager wm = (WindowManager) context
                        .getSystemService(Activity.WINDOW_SERVICE);
                wm.removeView(view_obj);
            }
        }

        /**
         * 更新弹出窗口位置
         */
        private static void updateViewPosition(View view) {
            // 更新浮动窗口位置参数
            params.x = (int) (x - mTouchStartX);
            params.y = (int) (y - mTouchStartY);
            wm.updateViewLayout(FloatingFunc.floatingViewObj, params);
        }

    }

    测试代码,放到任意的 Activity 代码里就可以,可以用手拖动位置

    final TextView tv = new TextView(getApplicationContext());
                    tv.setText("http://www.my400800.cn ");
                    view.setOnTouchListener(new View.OnTouchListener() {
                       
                        @Override
                        public boolean onTouch(View arg0, MotionEvent arg1) {
                            FloatingFunc.onTouchEvent(arg1, tv);
                            return true;
                        }
                    });

    效果如下:


    注意事项:

    一定要在AndroidManifest.xml添加

        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    系统权限,不然会出错的呀。。。。。。。。。。。。。

  • 相关阅读:
    SGI STL堆heap
    Linux高级I/O函数 mmap, munmap
    SGI STL队列queue
    std::is_convertible 判断类型转换
    Linux高级I/O函数 tee
    算法笔记:并查集
    Linux 用户信息、切换用户
    Linux高级I/O函数 fcntl()
    std::is_trivially_destructible 判断一个类型是否是一个平凡的可销毁类型
    Linux 最大文件描述符数
  • 原文地址:https://www.cnblogs.com/jishu/p/2220377.html
Copyright © 2020-2023  润新知