欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现悬浮窗体效果

程序员文章站 2023-08-31 13:58:38
突然对悬浮窗体感兴趣,查资料做了个小demo,效果是点击按钮后,关闭当前activity,显示悬浮窗口,窗口可以拖动,双击后消失。效果图如下: 它的使用原理很简单,就...

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

Android实现悬浮窗体效果

它的使用原理很简单,就是借用了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;

 }

}

 源代码地址:android实现悬浮窗体效果

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