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

时间:2023-02-08 21:25:27

今天发现一些软件可以在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;
                    }
                });

 

 

效果如下:


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

 

注意事项:

 

一定要在AndroidManifest.xml添加

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

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