zoukankan      html  css  js  c++  java
  • 【Android Demo】悬浮窗体实现

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

    它的使用原理很简单,就是借用了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 代码如下:

    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灬叶小超原创,如有转载请注明出处,谢谢!

  • 相关阅读:
    并发容器之CopyOnWriteArrayList
    Python os.listdir() 方法
    Python os.link() 方法
    Python os.lchown() 方法
    Python os.lchmod() 方法
    Python os.lchflags() 方法
    APP test
    jmeter 启动报错:not able to find java executable or version
    sqlserver数据库性能测试方法
    jmeter基础概念
  • 原文地址:https://www.cnblogs.com/yc-755909659/p/4281214.html
Copyright © 2011-2022 走看看