读书人

悬浮窗口的兑现

发布时间: 2012-09-25 09:55:59 作者: rapoo

悬浮窗口的实现
最近一些软件有了很牛X的悬浮窗口功能,很好奇怎么实现的,刚刚终于弄出来了...原理就是调用WindowManager直接操控View,然后再配合相应的WindowManager.LayoutParams属性,就OK了。这样产生出来的View根据LayoutParams的属性不同,效果也不一样。有关具体的属性,请自行参考SDK文档。

以下代码请仅供演示:

public class myFloatView extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        Button bb=new Button(getApplicationContext());        WindowManager wm=(WindowManager)getApplicationContext().getSystemService("window");        WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();        wmParams.type=2002;  //type是关键,这里的2002表示系统级窗口,你也可以试试2003。        wmParams.format=1;        wmParams.flags=40;        wmParams.width=40;        wmParams.height=40;        wm.addView(bb, wmParams);    }



以下转自:http://blog.csdn.net/ljl_xyf/article/details/6894220
今天发现一些软件可以在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");tv.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View arg0, MotionEvent arg1) {FloatingFunc.onTouchEvent(arg1, tv);return true;}});


效果如下:



注意事项:
一定要在AndroidManifest.xml添加
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

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

读书人网 >移动开发

热点推荐