WindowManager实现浮动在最顶层视图

  1. WindowManager的api的讲解:
    public interface
    WindowManager
    implements ViewManager
    android.view.WindowManager
    Class Overview

The interface that apps use to talk to the window manager.

Use Context.getSystemService(Context.WINDOW_SERVICE) to get one of these.

Each window manager instance is bound to a particular Display. To obtain a WindowManager for a different display, use createDisplayContext(Display) to obtain a Context for that display, then use Context.getSystemService(Context.WINDOW_SERVICE) to get the WindowManager.

The simplest way to show a window on another display is to create a Presentation. The presentation will automatically obtain a WindowManager and Context for that display.

See Also

getSystemService(String)
WINDOW_SERVICE

Summary
Nested Classes
class WindowManager.BadTokenException Exception that is thrown when trying to add view whose WindowManager.LayoutParams token is invalid.
class WindowManager.InvalidDisplayException Exception that is thrown when calling addView(View, ViewGroup.LayoutParams) to a secondary display that cannot be found.
class WindowManager.LayoutParams
Public Methods
abstract Display getDefaultDisplay()
Returns the Display upon which this WindowManager instance will create new windows.
abstract void removeViewImmediate(View view)
Special variation of removeView(View) that immediately invokes the given view hierarchy’s View.onDetachedFromWindow() methods before returning.
[Expand]
Inherited Methods
From interface android.view.ViewManager

  • 从这段英文说明中我们可以知道Windowmanager 是怎样实例化的:
    Windowmanager manager = Context.getSystemService(Context.WINDOW_SERVICE)
  • 如何我们想要展现的视图添加到Windowmanager 中去:
    manager .addView ( View v )
  • 如何更新当前视图对话框
    windowManager.updateViewLayout( view , params );
    params 这个参数包装了windowManager的一系列的配置
  • WindowManager.LayoutParams 官网Api文档解释:http://www.android-doc.com/reference/android/view/WindowManager.LayoutParams.html
  • 如何释放WindowManager中的view :
  if (windowManager!=null){
            windowManager.removeViewImmediate(linearLayout);
            windowManager = null ;
        }

2、自己写的WindowManager简单的案例
WindowManager实现浮动在最顶层视图_第1张图片

  • 首先需要引入权限

  • 6.0以上的系统 动态的授权
@TargetApi(Build.VERSION_CODES.M)
    private void getOverlayPermission() {
        if (!Settings.canDrawOverlays(MainActivity.this)){
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, 0);
        }else {
          showWindowManager();
        }
    }

  • 完整的代码:
public class MainActivity extends AppCompatActivity {

    private int lastX ;
    private ImageView imageView ;
    private WindowManager windowManager;
    private WindowManager.LayoutParams params;
    private LinearLayout linearLayout;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        /**添加悬浮图片的手势*/
        setOnTouchListener();
        /**显示顶层的权限*/
        getOverlayPermission();
    }



    private void initView() {
        linearLayout=new LinearLayout(this);
        linearLayout.setPadding(10,10,10,10);
        imageView=new ImageView(this);
        imageView.setImageResource(R.drawable.d_small);
        linearLayout.addView(imageView);

        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP){
            ImageView im=findViewById(R.id.tv_);
            im.setTranslationZ(100);
            imageView.animate().translationZ(10);
        }
    }


    private void setOnTouchListener() {
        linearLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 获取当前点的xy位置
                int currentX = (int) event.getRawX();
                int currentY = (int) event.getRawY();
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        lastX = currentX ;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (Math.abs(currentX - lastX)> ViewConfiguration.get(MainActivity.this).getScaledTouchSlop()){
                            params.x =  (currentX - linearLayout.getWidth()/2);
                            params.y =  currentY - linearLayout.getHeight();
                            windowManager.updateViewLayout(linearLayout,params);
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                        if (params.x>(getResources().getDisplayMetrics().widthPixels - linearLayout.getMeasuredWidth())/2){
                            params.x = getResources().getDisplayMetrics().widthPixels - linearLayout.getMeasuredWidth();
                        }else {
                            params.x = 0;
                        }
                        windowManager.updateViewLayout(linearLayout,params);
                        break;
                }
                return true;
            }
        });
    }




    //请求悬浮窗权限
    @TargetApi(Build.VERSION_CODES.M)
    private void getOverlayPermission() {
        if (!Settings.canDrawOverlays(MainActivity.this)){
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, 0);
        }else {
          showWindowManager();
        }
    }


    /**
     * 初始化  配置悬浮图片
     */
    private void showWindowManager() {
        windowManager=getWindowManager();
        params = new WindowManager.LayoutParams(200,200,0);
        params.type = WindowManager.LayoutParams.TYPE_PHONE;
        params.gravity = Gravity.LEFT | Gravity.TOP;
        params.x = getResources().getDisplayMetrics().widthPixels - linearLayout.getMeasuredWidth();
        params.y = 100;
        params.width=200;
        params.height=200;
//        params.flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
//                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
//                        WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
//                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

        params.format = PixelFormat.TRANSLUCENT;
        windowManager.addView(linearLayout,params);
    }


    /**
     * 接收   权限开启结果
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode==RESULT_OK){
            if (requestCode == 0){
                showWindowManager();
            }
        }
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (windowManager!=null){
            windowManager.removeView(linearLayout);
            windowManager = null ;
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }



    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (windowManager!=null){
            windowManager.removeViewImmediate(linearLayout);
            windowManager = null ;
        }
    }

你可能感兴趣的:(工作笔记)