Android使用WindowManager在界面添加一个悬浮框

来源:互联网 发布:数据分析属于什么专业 编辑:程序博客网 时间:2024/05/16 00:50

项目中需要在一个service里面显示一个悬浮框,刚开始用一个对话框,但是对话框有背景,而且对话框不好控制,后来使用WindowManger实现需求。
需求是:A项目有一个service用来监听用户说的话;B项目就一个界面,基本设置的
要是实现,B项目界面启动,调用A的service来监听用户说的话,所以要在service上悬浮一个标志,代表目前是监听用户说话,还是未监听状态;并且实现悬浮框随意移动。

实现步骤:
1,先自己定义了一个布局类作为悬浮的视图;
代码:

public class ForewarnLayout extends RelativeLayout {    private float mTouchX;    private float mTouchY;    private float x;    private float y;    private float mStartX;    private float mStartY;    // 窗口视图    private WindowManager mWindowManager;    private WindowManager.LayoutParams mLayoutParams;    private OnClickListener mOnClickListener;    //语音图片    private ImageView voiceBtn = null;    private View mView = null;    private static int sign = 1;    public ForewarnLayout(Context context) {        super(context);        WindowManager.LayoutParams myparams = new WindowManager.LayoutParams();        myparams.height = LayoutParams.WRAP_CONTENT;        myparams.width = LayoutParams.WRAP_CONTENT;        this.setLayoutParams(myparams);        // 加载布局        LayoutInflater lf = LayoutInflater.from(context);        mWindowManager = (WindowManager) context.getApplicationContext()                .getSystemService(Context.WINDOW_SERVICE);        mLayoutParams = new WindowManager.LayoutParams();        mView = lf.inflate(R.layout.forewarn_layout, null);        this.addView(mView, myparams);        voiceBtn = (ImageView) findViewById(R.id.serviceVoiceBtn);    }    /**     * tounch事件     */    @Override    public boolean onTouchEvent(MotionEvent event) {        // 获取到状态栏的高度        Rect frame = new Rect();        getWindowVisibleDisplayFrame(frame);        int statusBarHeight = frame.top;        System.out.println("statusBarHeight:" + statusBarHeight);        // 获取相对屏幕的坐标,即以屏幕左上角为原点        x = event.getRawX();        y = event.getRawY() - statusBarHeight; // statusBarHeight是系统状态栏的高度        Log.i("tag", "currX" + x + "====currY" + y);        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN: // 捕获手指触摸按下动作            // 获取相对View的坐标,即以此View左上角为原点            mTouchX = event.getX();            mTouchY = event.getY();            mStartX = x;            mStartY = y;            Log.i("tag", "startX" + mTouchX + "====startY" + mTouchY);            break;        case MotionEvent.ACTION_MOVE: // 捕获手指触摸移动动作            updateViewPosition();            break;        case MotionEvent.ACTION_UP: // 捕获手指触摸离开动作            updateViewPosition();            mTouchX = mTouchY = 0;            if ((x - mStartX) < 2 && (y - mStartY) < 2) {                // 设置监听                if (mOnClickListener != null) {                    mOnClickListener.onClick(this);                }            }            break;        }        return true;    }    // 更新浮动窗口位置参数    private void updateViewPosition() {        mLayoutParams.x = (int) (x - mTouchX);        mLayoutParams.y = (int) (y - mTouchY);        mWindowManager.updateViewLayout(this, mLayoutParams); // 刷新显示    }    // 获取界面布局参数对象    public WindowManager.LayoutParams getLayoutParams() {        return mLayoutParams;    }    // 设置界面布局参数    public void setWmParams(WindowManager.LayoutParams layoutParams) {        mLayoutParams = layoutParams;    }    // 界面点击事件监听    @Override    public void setOnClickListener(OnClickListener listener) {        mOnClickListener = listener;    }    /**     * 设置语音浮动按钮状态     *      * @param type     */    public void setVoiceBtnType(int type) {        // 录音        if (type == 1) {            voiceBtn.setImageResource(R.drawable.voice_bar_click_ok_pressed);            // 暂停录音        } else if (type == 0) {            voiceBtn.setImageResource(R.drawable.voice_bar_click_normal);        }    }}

2,service里面写了一个创建悬浮视图的方法

private WindowManager mwWindowManager = null;private ForewarnLayout mForewarnLayout;/**     * 浮动框视图     */    private void createForewarnLayout() {        mForewarnLayout = new ForewarnLayout(getApplicationContext());        // 浮动视图点击事件        mForewarnLayout.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {            }        });        // 获取window管理对象        mwWindowManager = (WindowManager) getApplicationContext()                .getSystemService(Context.WINDOW_SERVICE);        // 设置布局参数        LayoutParams forewarnLayoutParams = mForewarnLayout.getLayoutParams();        forewarnLayoutParams.type = LayoutParams.TYPE_PHONE; // 设置window TYPE        forewarnLayoutParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果位背景透明        // 设置Window flag        forewarnLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL                | LayoutParams.FLAG_NOT_FOCUSABLE;        forewarnLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; //        // 调整悬浮窗口至左上角,便于调整坐标        // 以屏幕左上角为原点,设置X y初始值        forewarnLayoutParams.x = 250;        forewarnLayoutParams.y = 2;        // 设置悬浮窗口长宽数据        forewarnLayoutParams.width = LayoutParams.WRAP_CONTENT;        forewarnLayoutParams.height = LayoutParams.WRAP_CONTENT;        // forewarnLayoutParams.windowAnimations = R.style.anim_view;// 添加进入动画        // 添加布局视图        mwWindowManager.addView(mForewarnLayout, forewarnLayoutParams);    }

3,然后在service的onbind方法调用createForewarnLayout()方法,
service销毁需要移除视图,

// 移除浮动框        if (mwWindowManager != null) {            mwWindowManager.removeView(mForewarnLayout);        }

终结:WindowManager Android窗口管理类,可以理解为当前的屏幕,可以对视图添加,删除等处理。

0 0
原创粉丝点击