突然对悬浮窗体感兴趣,查资料做了个小Demo,效果是点击按钮后,关闭当前Activity,显示悬浮窗口,窗口可以拖动,双击后消失。效果图如下:

【Android Demo】悬浮窗体实现

它的使用原理很简单,就是借用了WindowManager这个管理类来实现的。
1.首先在AndroidManifest.xml中添加使用权限:

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

2.悬浮窗口布局实现

public class DesktopLayout extends LinearLayout {    public DesktopLayout(Context context) {        super(context);        setOrientation(LinearLayout.VERTICAL);// 水平排列                //设置宽高        this.setLayoutParams( new LayoutParams(LayoutParams.WRAP_CONTENT,                LayoutParams.WRAP_CONTENT));                View view = LayoutInflater.from(context).inflate(                  R.layout.desklayout, null);         this.addView(view);    }

3.在activity中让它显示出来。

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

详细 MainActivity 代码如下:

【Android Demo】悬浮窗体实现
package com.yc.yc_suspendingform;import android.app.Activity;import android.graphics.PixelFormat;import android.graphics.Rect;import android.os.Bundle;import android.util.Log;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;import com.yc.yc_floatingform.R;public class MainActivity extends Activity {    private WindowManager mWindowManager;    private WindowManager.LayoutParams mLayout;    private DesktopLayout mDesktopLayout;    private long startTime;    // 声明屏幕的宽高    float x, y;    int top;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                createWindowManager();        createDesktopLayout();        Button btn = (Button) findViewById(R.id.btn);        btn.setOnClickListener(new OnClickListener() {            public void onClick(View v) {                showDesk();            }        });    }    /**     * 创建悬浮窗体     */    private void createDesktopLayout() {        mDesktopLayout = new DesktopLayout(this);        mDesktopLayout.setOnTouchListener(new OnTouchListener() {            float mTouchStartX;            float mTouchStartY;            @Override            public boolean onTouch(View v, MotionEvent event) {                // 获取相对屏幕的坐标,即以屏幕左上角为原点                x = event.getRawX();                y = event.getRawY() - top; // 25是系统状态栏的高度                Log.i("startP", "startX" + mTouchStartX + "====startY"                        + mTouchStartY);                switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    // 获取相对View的坐标,即以此View左上角为原点                    mTouchStartX = event.getX();                    mTouchStartY = event.getY();                    Log.i("startP", "startX" + mTouchStartX + "====startY"                            + mTouchStartY);                    long end = System.currentTimeMillis() - startTime;                    // 双击的间隔在 300ms以下                    if (end < 300) {                        closeDesk();                    }                    startTime = System.currentTimeMillis();                    break;                case MotionEvent.ACTION_MOVE:                    // 更新浮动窗口位置参数                    mLayout.x = (int) (x - mTouchStartX);                    mLayout.y = (int) (y - mTouchStartY);                    mWindowManager.updateViewLayout(v, mLayout);                    break;                case MotionEvent.ACTION_UP:                    // 更新浮动窗口位置参数                    mLayout.x = (int) (x - mTouchStartX);                    mLayout.y = (int) (y - mTouchStartY);                    mWindowManager.updateViewLayout(v, mLayout);                    // 可以在此记录最后一次的位置                    mTouchStartX = mTouchStartY = 0;                    break;                }                return true;            }        });    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        Rect rect = new Rect();        // /取得整个视图部分,注意,如果你要设置标题样式,这个必须出现在标题样式之后,否则会出错        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);        top = rect.top;//状态栏的高度,所以rect.height,rect.width分别是系统的高度的宽度        Log.i("top",""+top);    }    /**     * 显示DesktopLayout     */    private void showDesk() {        mWindowManager.addView(mDesktopLayout, mLayout);        finish();    }    /**     * 关闭DesktopLayout     */    private void closeDesk() {        mWindowManager.removeView(mDesktopLayout);        finish();    }    /**     * 设置WindowManager     */    private void createWindowManager() {        // 取得系统窗体        mWindowManager = (WindowManager) getApplicationContext()                .getSystemService("window");        // 窗体的布局样式        mLayout = new WindowManager.LayoutParams();        // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)        mLayout.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;        // 设置窗体焦点及触摸:        // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)        mLayout.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        // 设置显示的模式        mLayout.format = PixelFormat.RGBA_8888;        // 设置对齐的方法        mLayout.gravity = Gravity.TOP | Gravity.LEFT;        // 设置窗体宽度和高度        mLayout.width = WindowManager.LayoutParams.WRAP_CONTENT;        mLayout.height = WindowManager.LayoutParams.WRAP_CONTENT;    }}
View Code

源代码地址:https://github.com/YeXiaoChao/Yc_suspendingform

本文地址:www.cnblogs.com/yc-755909659/p/4281214.html

PS:本文由J灬叶小超原创,如有转载请注明出处,谢谢!

更多相关文章

  1. Android: HowTo设置app不被系统kill掉
  2. Android调用系统Email发送邮件
  3. android系统框架()
  4. windows系统Android模拟器安装apk
  5. Android用户apk如何获得系统(system)权限
  6. Android 学生管理系统 之 SQLite数据库操作
  7. Android 系统稳定性之ANR
  8. Android编译系统详解

随机推荐

  1. #android training# Graphics & Animatio
  2. Android(安卓)Getting Started
  3. android SpannableString使用详解
  4. Android(安卓)Linux usb gadget configfs
  5. android DatePicker
  6. android 图片背景使用这种方式很爽
  7. Android(安卓)SDK r16 发布
  8. Android旋转动画不停顿
  9. Android(安卓)自制一个工作日历 原代码
  10. Android之qq盗号