Android使用WindowManager构造悬浮view

所属分类: 软件编程 / Android 阅读数: 873
收藏 0 赞 0 分享

一般在android显示一个View都是通过Activity的setContentView设置的,但是还有一种方法,可以直接使用WindowManager在整个应用的最上层绘制我们需要显示的view,总体的效果类似于AlertDialog的弹出效果。

使用WindowManager构造这样的一个悬浮View也比较简单,直接通过windowmanager.addView()方法即可。

package com.gearmotion.app.windowmanagermotion;

import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {

 Button mShowBtn;
 Button mHideBtn;
 WindowManager mWm;
 LayoutInflater mLayoutInflater;
 View mWindowView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mShowBtn = (Button) this.findViewById(R.id.showbtn);
  mHideBtn = (Button) this.findViewById(R.id.hidebtn);
  mShowBtn.setOnClickListener(this);
  mHideBtn.setOnClickListener(this);
  init();
 }

 private void init() {
  mWm = (WindowManager) this.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
  mLayoutInflater = LayoutInflater.from(this);
 }

 @Override
 public void onClick(View v) {
  if (mShowBtn.hashCode() == v.hashCode()) { //显示WindowManager
   show();
  }
  if (mHideBtn.hashCode() == v.hashCode()) { //隐藏windowmanager
   hide();
  }
 }

 private void show() {
  mWindowView = mLayoutInflater.inflate(R.layout.item_layout, null);
  View popView = mWindowView.findViewById(R.id.root);
  //设置popView的触摸事件,以便点击空白区域的时候使悬浮view消失
  popView.setOnTouchListener(this);
  WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
  //窗口类型同系统弹出框
  lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
  //响应输入法
  //lp.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
  //透明层
  lp.format = PixelFormat.TRANSPARENT;
  lp.width = WindowManager.LayoutParams.MATCH_PARENT;
  lp.height = WindowManager.LayoutParams.MATCH_PARENT;
  lp.gravity = Gravity.CENTER_VERTICAL;
  mWm.addView(mWindowView, lp);
 }

 private void hide() {
  if (mWindowView != null && mWindowView.getParent() != null) {
   mWm.removeView(mWindowView);
  }
 }

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  int x = (int) event.getX();
  int y = (int) event.getY();
  //获取主view的可视区域
  Rect globalRect = new Rect();
  //获取悬浮view的可视区域
  Rect tmpRect = new Rect();
  v.getGlobalVisibleRect(globalRect);
  View child = ((ViewGroup) v).getChildAt(0);
  child.getHitRect(tmpRect);
  if (!tmpRect.contains(x, y) && globalRect.contains(x, y)) {
   hide();
  }
  return true;
 }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity">

 <Button
  android:id="@+id/showbtn"
  android:layout_width="match_parent"
  android:layout_height="50dp"
  android:gravity="center"
  android:text="show" />

 <Button
  android:id="@+id/hidebtn"
  android:layout_width="match_parent"
  android:layout_height="50dp"
  android:gravity="center"
  android:text="hide" />
</LinearLayout>

item_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:gravity="center"
 android:id="@+id/root"
 android:orientation="vertical">

 <TextView
  android:layout_width="match_parent"
  android:layout_height="50dp"
  android:text="I am WindowManager layout view"
  android:textSize="20sp"
  android:gravity="center"
  android:layout_gravity="center"
  android:background="#FFF8DC"
  android:textColor="#7AC5CD"/>
</LinearLayout>

实现效果如下:

以上就是本文的全部内容,希望对大家学习Android有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Android中加入名片扫描功能实例代码

这篇文章主要介绍了Android中加入名片扫描功能实例代码的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android仿微信发表说说实现拍照、多图上传功能

这篇文章主要为大家详细介绍了Android仿微信发表说说实现拍照、多图上传功能,使用Retrofit2.0技术,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

设置Android系统永不锁屏永不休眠的方法

在进行Android系统开发的时候,有些特定的情况需要设置系统永不锁屏,永不休眠。本篇文章给大家介绍Android 永不锁屏,开机不锁屏,删除设置中休眠时间选项,需要的朋友一起学习吧
收藏 0 赞 0 分享

Android Retrofit 2.0框架上传图片解决方案

这篇文章主要介绍了Android Retrofit 2.0框架上传一张与多张图片解决方案,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android自定义等待对话框

这篇文章主要为大家详细介绍了Android自定义等待对话框的实现方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android中Window添加View的底层原理

这篇文章主要介绍了Android中Window添加View的底层原理,需要的朋友可以参考下
收藏 0 赞 0 分享

Android调用系统默认浏览器访问的方法

这篇文章主要介绍了Android调用系统默认浏览器访问的方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android开发退出程序的方法汇总

Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗口B后,在B中如何关闭整个Android应用程序呢? 下面脚本之家小编就给大家介绍android开发退出程序的几种方法,感兴趣的朋友参考下吧
收藏 0 赞 0 分享

Android程序开发中单选按钮(RadioGroup)的使用详解

在android程序开发中,无论是单选按钮还是多选按钮都非常的常见,接下来通过本文给大家介绍Android程序开发中单选按钮(RadioGroup)的使用,需要的朋友参考下吧
收藏 0 赞 0 分享

Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中

这篇文章主要介绍了Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多