• Android WindowManager实现悬浮窗效果 (一)——与当前Activity绑定


    最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。

    第一步:认识WindowManager

    l  这个接口用于与 window manager (窗口管理器, 应用框架层) 进行交互。

    l  通过getSystemService(Context.WINDOW_SERVICE)可以获取到WM的实例.

    l  继承关系

           public interface WindowManager implements ViewManager

    l  所属包

           android.view.WindowManager

    l  重要方法

    addView()             添加view

    removeView()          删除view

    updateViewLayout ()     改变view的参数

      Window Manager Service 是全局的,是唯一的。 它将用户的操作,翻译成为指令,发送给呈现在界面上的各个WindowActivity会将顶级的控件注册到 Window Manager 中,当用户真是触碰屏幕或键盘的时候,Window Manager就会通知到,而当控件有一些请求产生,也会经由ViewParent送回到Window Manager中。从而完成整个通信流程

    第二步:重写ImageView 的onTouchEvent方法

    上一步我们知道了 WindowManager可以添加,删除,改变view,那么想要实现悬浮窗的拖动效果我们就要获取ImageView的坐标位置。

    l  获取相对屏幕的坐标,即以屏幕左上角为原点

           float  x = event.getRawX();

           float  y = event.getRawY()-25;   //25是系统状态栏的高度

    l  通过WindowManager.LayoutParams wmParams 设置 x ,y

      wmParams.x=(int)( x-mTouchStartX);

            wmParams.y=(int) (y-mTouchStartY);

    l  再通过updateViewLayout()方法设置悬浮窗的当前位置

    第三步:加入权限

      在AndroidManifest.xml中加入如下的权限:

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

      效果如下:

      重要代码 :   创建 MyApplication

    import android.app.Application;
    import android.view.WindowManager;
    
    public class MyApplication extends Application {
    
        /**
         * 创建全局变量
         * 注意在AndroidManifest.xml中的Application节点添加android:name=".MyApplication"属性
         *
         */
        private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();
    
        public WindowManager.LayoutParams getMywmParams(){
            return wmParams;
        }
    }

      创建自定义View 继承ImageView

    import android.content.Context;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.WindowManager;
    import android.widget.ImageView;
    
    public class MyFloatView extends ImageView {
        private float mTouchStartX;
        private float mTouchStartY;
        private float x;
        private float y;
    
    
        private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
    
        //此wmParams为获取的全局变量,用以保存悬浮窗口的属性
        private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams();
    
        public MyFloatView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //获取相对屏幕的坐标,即以屏幕左上角为原点
            x = event.getRawX();
            y = event.getRawY()-25;   //25是系统状态栏的高度
            Log.i("currP", "currX"+x+"====currY"+y);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //获取相对View的坐标,即以此View左上角为原点
                    mTouchStartX =  event.getX();
                    mTouchStartY =  event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    updateViewPosition();
                    break;
                case MotionEvent.ACTION_UP:
                    updateViewPosition();
                    mTouchStartX=mTouchStartY=0;
                    break;
            }
            return true;
        }
    
        private void updateViewPosition(){
            //更新浮动窗口位置参数
            wmParams.x=(int)( x-mTouchStartX);
            wmParams.y=(int) (y-mTouchStartY);
            wm.updateViewLayout(this, wmParams);
        }
    
    }

      创建Activity

    import android.app.Activity;
    
    import android.content.Context;
    import android.graphics.PixelFormat;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.View;
    import android.view.WindowManager;
    import android.view.View.OnClickListener;
    import android.view.WindowManager.LayoutParams;
    
    public class MyFloatViewActivity extends Activity{
    
        private WindowManager wm=null;
        private WindowManager.LayoutParams wmParams=null;
        private MyFloatView myFV=null;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            //创建悬浮窗口
            createView();
        }
        private void createView(){
            myFV=new MyFloatView(getApplicationContext());
            myFV.setImageResource(R.drawable.angry_birds);
            //获取WindowManager
            wm=(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
            //设置LayoutParams(全局变量)相关参数
            wmParams = ((MyApplication)getApplication()).getMywmParams();
            wmParams.type=LayoutParams.TYPE_PHONE;   //设置window type
            wmParams.format=PixelFormat.RGBA_8888;   //设置图片格式,效果为背景透明
            //设置Window flag
            wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | LayoutParams.FLAG_NOT_FOCUSABLE;
            wmParams.gravity=Gravity.LEFT|Gravity.TOP;   //调整悬浮窗口至左上角
            //以屏幕左上角为原点,设置x、y初始值
            wmParams.x=0;
            wmParams.y=0;
            //设置悬浮窗口长宽数据
            wmParams.width=40;
            wmParams.height=40;
            //显示myFloatView图像
            wm.addView(myFV, wmParams);
    
        }
        @Override
        public void onDestroy(){
            super.onDestroy();
            //在程序退出(Activity销毁)时销毁悬浮窗口
            wm.removeView(myFV);
        }
    }

      l  最后在程序安装时修改手机里的程序权限-》悬浮窗可用

    作者:杰瑞教育
    出处:http://www.cnblogs.com/jerehedu/ 
    版权声明:本文版权归杰瑞教育技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    技术咨询:JRedu技术交流
     
  • 相关阅读:
    hdu5014——构造打表找规律
    HDU5124,线段树加离散化
    hdu 3400-三分套三分
    三分法——凸函数求极值问题
    Zoj 3811并查集
    iOS更新之DFU模式和恢复模式
    获取安卓系统版本
    (转)25个增强iOS应用程序性能的提示和技巧--高级篇
    (转)25个增强iOS应用程序性能的提示和技巧--中级篇
    (转)25个增强iOS应用程序性能的提示和技巧--初级篇
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4981188.html
Copyright © 2020-2023  润新知