工作中遇到一些项目需要把窗体显示在最上层,像来电弹窗显示电话号码等信息或拦截短信信息显示给用户,我们想这些数据放在最上层,activity就满足不了我们的需求了,有些开发者使用了循环显示Toast的方式,toast是不能获得焦点的,这种方法是不可取的。这个时候,我们如何处理呢?
原来,整个Android的窗口机制是基于一个叫做 WindowManager,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽略我们以前的Activity或者Dialog之类的东东。其实我们的Activity或者Diolog底层的实现也是通过WindowManager,这个 WindowManager是全局的,整个系统就是这个唯一的东东。它是显示View的最底层了。

WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.

WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:

* addView();

* updateViewLayout();

* removeView();

效果图如下:

Android UI开发第十四篇——可以移动的悬浮框_第1张图片

可以移动的悬浮框实现代码如下:

public class WindowManageDemoActivity extends Activity { private WindowManager mWindowManager; private WindowManager.LayoutParams param; private FloatView mLayout;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                      showView();    }    private void showView(){     mLayout=new FloatView(getApplicationContext());     mLayout.setBackgroundResource(R.drawable.faceback_head);     //获取WindowManager     mWindowManager=(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);        //设置LayoutParams(全局变量)相关参数     param = ((MyApplication)getApplication()).getMywmParams();     param.type=WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;     // 系统提示类型,重要     param.format=1;     param.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不能抢占聚焦点     param.flags = param.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;     param.flags = param.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; // 排版不受限制           param.alpha = 1.0f;             param.gravity=Gravity.LEFT|Gravity.TOP;   //调整悬浮窗口至左上角        //以屏幕左上角为原点,设置x、y初始值     param.x=0;     param.y=0;                //设置悬浮窗口长宽数据     param.width=140;     param.height=140;                //显示myFloatView图像     mWindowManager.addView(mLayout, param);         }    @Override    public void onDestroy(){     super.onDestroy();     //在程序退出(Activity销毁)时销毁悬浮窗口     mWindowManager.removeView(mLayout);    }}


public class FloatView extends View { private float mTouchStartX;    private float mTouchStartY;    private float x;    private float y;        private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);    private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams(); public FloatView(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();                             Log.i("startP", "startX"+mTouchStartX+"====startY"+mTouchStartY);                          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);       }}


public class MyApplication extends Application { /**  * 创建全局变量  * 全局变量一般都比较倾向于创建一个单独的数据类文件,并使用static静态变量  *   * 这里使用了在Application中添加数据的方法实现全局变量  * 注意在AndroidManifest.xml中的Application节点添加android:name=".MyApplication"属性  *   */ private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams(); public WindowManager.LayoutParams getMywmParams(){  return wmParams; }}


/**
* @author 张兴业
* 邮箱:xy-zhang#163.com
* android开发进阶群:278401545
*
*/

参考:

Android平台WindowManager运用

Android 之 Window、WindowManager 与窗口管理

更多相关文章

  1. Android实现系统级屏幕录制(上)
  2. Android护眼模式、屏幕亮度调节功能开发【基于Android8.0】
  3. Android之屏幕适配
  4. Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析
  5. Android官方开发中心之Web Apps屏幕适配
  6. Android X86强制竖屏怎么办?安卓(Android)x86屏幕旋转成横屏解决
  7. Android录制屏幕的实现方法

随机推荐

  1. React Native 环境变量配置(window7)
  2. Android(安卓)架构师之路22 响应式编程Rx
  3. Android封装SDK生成Jar包以及混淆的方法
  4. Android(安卓)Material Design-UI
  5. android自己添加的模块在user模式下不编
  6. Android如何读写CSV文件方法示例
  7. android之IntentFilter的用法_Intent.ACT
  8. unity项目中,需要将文本内容复制到系统剪
  9. Android打开手机相册获取图片路径
  10. Permission Denial: opening provider 隐