移动云

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 5111|回复: 0

类似Andriod QQ手机关家的那种悬浮窗体

[复制链接]
发表于 2013-3-29 11:59:08 | 显示全部楼层 |阅读模式

用过手机360和QQ手机管家等一些软件的朋友,会发现,在这些应用中,会出现一个悬浮窗体,例如QQ手机管家中打电话的场景:


这种窗体除了会显示外,还可以移动它的位置,并且一直显示。除了关闭当前程序外,窗口不会主动消失。其实,它的使用原理也很简单,就是借用了WindowManager这个管理类来实现的。
注意:要在AndroidManifest.xml中添加使用权限:

[html] view plaincopy


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


这里,我采用代码布局的方式,模仿了一下QQ这个界面效果:
[java] view plaincopy


  • import android.content.Context;  
  • import android.widget.ImageView;  
  • import android.widget.LinearLayout;  
  • import android.widget.TextView;  
  •   
  • public class DesktopLayout extends LinearLayout {  
  •   
  •     public DesktopLayout(Context context) {  
  •         super(context);  
  •         setOrientation(LinearLayout.HORIZONTAL);  
  •         LayoutParams mLayoutParams = new LayoutParams(  
  •                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  •         setLayoutParams(mLayoutParams);  
  •   
  •         // 显示的ICON  
  •         ImageView mImageView = new ImageView(context);  
  •         mImageView.setImageResource(R.drawable.icon);  
  •         addView(mImageView, mLayoutParams);  
  •   
  •         // 显示的文字  
  •         TextView mTextView = new TextView(context);  
  •         mTextView.setText("Hello");  
  •         mTextView.setTextSize(30);  
  •         addView(mTextView, mLayoutParams);  
  •     }  
  • }  


接下来,在activity中让它显示出来。首先要设置一下WindowManager.LayoutParams:
[java] view plaincopy


  • // 取得系统窗体  
  • mWindowManager = (WindowManager) getApplicationContext()  
  •         .getSystemService("window");  
  •   
  • // 窗体的布局样式  
  • mLayoutParams = new WindowManager.LayoutParams();  
  •   
  • // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)  
  • mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;  
  •   
  • // 设置窗体焦点及触摸:  
  • // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)  
  • mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  •   
  • // 设置显示的模式  
  • mLayoutParams.format = PixelFormat.RGBA_8888;  
  •   
  • // 设置对齐的方法  
  • mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;  
  •   
  • // 设置窗体宽度和高度  
  • mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  
  • mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  
  •   
  • // 设置窗体显示的位置,否则在屏幕中心显示  
  • mLayoutParams.x = 50;  
  • mLayoutParams.y = 50;  


显示窗体与关闭窗体的方法:
[java] view plaincopy


  • mWindowManager.addView(mDesktopLayout, mLayoutParams);  
  •   
  • mWindowManager.removeView(mDesktopLayout);  


以下是activity的原代码,这里设计了一个双击关闭窗体的效果:
[java] view plaincopy


  • import android.app.Activity;  
  • import android.graphics.PixelFormat;  
  • import android.os.Bundle;  
  • import android.view.Gravity;  
  • import android.view.MotionEvent;  
  • import android.view.View;  
  • import android.view.View.OnClickListener;  
  • import android.view.View.OnTouchListener;  
  • import android.view.WindowManager;  
  • import android.widget.Button;  
  •   
  • public class DeskTip extends Activity {  
  •   
  •     private WindowManager mWindowManager;  
  •   
  •     private WindowManager.LayoutParams mLayoutParams;  
  •   
  •     private DesktopLayout mDesktopLayout;  
  •   
  •     private long starttime;  
  •   
  •     /**
  •      * 创建悬浮窗体
  •      */  
  •     private void createDesktopLayout() {  
  •         mDesktopLayout = new DesktopLayout(this);  
  •         mDesktopLayout.setOnTouchListener(new OnTouchListener() {  
  •             public boolean onTouch(View v, MotionEvent event) {  
  •                 onActionMove(event);  
  •                 return true;  
  •             }  
  •         });  
  •     }  
  •   
  •     /**
  •      * 设置WindowManager
  •      */  
  •     private void createWindowManager() {  
  •         // 取得系统窗体  
  •         mWindowManager = (WindowManager) getApplicationContext()  
  •                 .getSystemService("window");  
  •   
  •         // 窗体的布局样式  
  •         mLayoutParams = new WindowManager.LayoutParams();  
  •   
  •         // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)  
  •         mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;  
  •   
  •         // 设置窗体焦点及触摸:  
  •         // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)  
  •         mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  •   
  •         // 设置显示的模式  
  •         mLayoutParams.format = PixelFormat.RGBA_8888;  
  •   
  •         // 设置对齐的方法  
  •         mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;  
  •   
  •         // 设置窗体宽度和高度  
  •         mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  
  •         mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  
  •   
  •         // 设置窗体显示的位置,否则在屏幕中心显示  
  •         mLayoutParams.x = 50;  
  •         mLayoutParams.y = 50;  
  •     }  
  •   
  •     private void onActionMove(MotionEvent event) {  
  •   
  •         if (event.getAction() == MotionEvent.ACTION_DOWN) {  
  •             long end = System.currentTimeMillis() - starttime;  
  •             // 双击的间隔在 200ms 到 500ms 之间  
  •             if (end > 200 && end < 500) {  
  •                 closeDesk();  
  •                 return;  
  •             }  
  •             starttime = System.currentTimeMillis();  
  •         }  
  •   
  •         mLayoutParams.x = (int) (event.getRawX() - (mDesktopLayout.getWidth()));  
  •         mLayoutParams.y = (int) (event.getRawY() - (mDesktopLayout.getHeight()));  
  •   
  •         mWindowManager.updateViewLayout(mDesktopLayout, mLayoutParams);  
  •     }  
  •   
  •     /**
  •      * 显示DesktopLayout
  •      */  
  •     private void showDesk() {  
  •         mWindowManager.addView(mDesktopLayout, mLayoutParams);  
  •         finish();  
  •     }  
  •   
  •     /**
  •      * 关闭DesktopLayout
  •      */  
  •     private void closeDesk() {  
  •         mWindowManager.removeView(mDesktopLayout);  
  •         finish();  
  •     }  
  •   
  •     public void onCreate(Bundle savedInstanceState) {  
  •         super.onCreate(savedInstanceState);  
  •         setContentView(R.layout.main);  
  •         createWindowManager();  
  •         createDesktopLayout();  
  •   
  •         Button btn = (Button) findViewById(R.id.btn);  
  •         btn.setOnClickListener(new OnClickListener() {  
  •             public void onClick(View v) {  
  •                 showDesk();  
  •             }  
  •         });  
  •     }  
  • }  


显示的效果:


转自http://blog.csdn.net/xyz_fly/article/details/7546096
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|管理员QQ:44994224|邮箱(t268studio@gmail.com)|Archiver|MCLOUDER

GMT+8, 2025-7-2 03:23 , Processed in 0.156522 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表