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

圣诞节,写个程序练练手————Android 全界面悬浮按钮实现

程序员文章站 2023-12-16 21:02:40
开始我以为悬浮窗口,可以用android中得popupwindow 来实现,虽然也实现了,但局限性非常大。比如popupwindow必须要有载体view,也就是说,必须要指...

开始我以为悬浮窗口,可以用android中得popupwindow 来实现,虽然也实现了,但局限性非常大。比如popupwindow必须要有载体view,也就是说,必须要指定在那个view的上面来实现。以该view为相对位置,来显示popupwindow。这就局限了其智能在用户交互的窗口上,相对的显示。而无法*的拖动位置和在桌面显示。

于是查阅了一些资料,有两种实现方法。一种是自定义toast,toast是运行于所有界面之上的,也就是说没有界面可以覆盖它。另一种是android中得compatmodewrapper类,conmpatmodewrapper是基类,实现大部分功能的是它的内部类windowmanagerimpl。该对象可以通过getapplication().getsystemservice(context.window_service)得到。(注:如果是通过activity.getsystemservice(context.window_service)得到的只是属于activity的localwindowmanager)。

简单的介绍之后,我们直接来看代码实现,注释已经写在代码中。

mainactivity.java
package com.example.floatviewdemo;
import com.example.floatviewdemo.service.floatviewservice;
import android.app.activity;
import android.content.intent;
import android.os.bundle;
public class mainactivity extends activity {
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
  }
  @override
 protected void onstart() {
  intent intent = new intent(mainactivity.this, floatviewservice.class); 
     //启动floatviewservice 
     startservice(intent); 
 super.onstart();
 }
 
 @override
 protected void onstop() {
 // 销毁悬浮窗
 intent intent = new intent(mainactivity.this, floatviewservice.class); 
    //终止floatviewservice 
    stopservice(intent); 
    super.onstop();
 }
}

activity_main.xml

<relativelayout 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:background="#fff"
  android:paddingbottom="@dimen/activity_vertical_margin"
  android:paddingleft="@dimen/activity_horizontal_margin"
  android:paddingright="@dimen/activity_horizontal_margin"
  android:paddingtop="@dimen/activity_vertical_margin"
  tools:context="com.example.floatviewdemo.mainactivity" >
  <textview
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />
</relativelayout>

实现悬浮窗功能的service类

package com.example.floatviewdemo.service;
import com.example.floatviewdemo.r;
import android.annotation.suppresslint;
import android.app.service;
import android.content.intent;
import android.graphics.pixelformat;
import android.os.ibinder;
import android.util.log;
import android.view.gravity;
import android.view.layoutinflater;
import android.view.motionevent;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.view.ontouchlistener;
import android.view.windowmanager;
import android.view.windowmanager.layoutparams;
import android.widget.imagebutton;
import android.widget.linearlayout;
import android.widget.toast;
public class floatviewservice extends service  
{ 
 private static final string tag = "floatviewservice"; 
  //定义浮动窗口布局 
  private linearlayout mfloatlayout; 
  private windowmanager.layoutparams wmparams; 
  //创建浮动窗口设置布局参数的对象 
  private windowmanager mwindowmanager; 
  private imagebutton mfloatview; 
  @override 
  public void oncreate()  
  { 
    super.oncreate(); 
    log.i(tag, "oncreate"); 
    createfloatview();    
  } 
  @suppresswarnings("static-access")
 @suppresslint("inflateparams") private void createfloatview() 
  { 
    wmparams = new windowmanager.layoutparams(); 
    //通过getapplication获取的是windowmanagerimpl.compatmodewrapper 
    mwindowmanager = (windowmanager)getapplication().getsystemservice(getapplication().window_service); 
    //设置window type 
    wmparams.type = layoutparams.type_phone;  
    //设置图片格式,效果为背景透明 
    wmparams.format = pixelformat.rgba_8888;  
    //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作) 
    wmparams.flags = layoutparams.flag_not_focusable;    
    //调整悬浮窗显示的停靠位置为左侧置顶 
    wmparams.gravity = gravity.left | gravity.top;     
    // 以屏幕左上角为原点,设置x、y初始值,相对于gravity 
    wmparams.x = 0; 
    wmparams.y = 152; 
    //设置悬浮窗口长宽数据  
    wmparams.width = windowmanager.layoutparams.wrap_content; 
    wmparams.height = windowmanager.layoutparams.wrap_content; 
    layoutinflater inflater = layoutinflater.from(getapplication()); 
    //获取浮动窗口视图所在布局 
    mfloatlayout = (linearlayout) inflater.inflate(r.layout.alert_window_menu, null); 
    //添加mfloatlayout 
    mwindowmanager.addview(mfloatlayout, wmparams); 
    //浮动窗口按钮 
    mfloatview = (imagebutton) mfloatlayout.findviewbyid(r.id.alert_window_imagebtn);
    mfloatlayout.measure(view.measurespec.makemeasurespec(0, 
        view.measurespec.unspecified), view.measurespec 
        .makemeasurespec(0, view.measurespec.unspecified)); 
    //设置监听浮动窗口的触摸移动 
    mfloatview.setontouchlistener(new ontouchlistener()  
    { 
     boolean isclick;
  @suppresslint("clickableviewaccessibility") @override
  public boolean ontouch(view v, motionevent event) {
  switch (event.getaction()) {
  case motionevent.action_down:
   mfloatview.setbackgroundresource(r.drawable.circle_red);
   isclick = false;
   break;
  case motionevent.action_move:
   isclick = true;
   // getrawx是触摸位置相对于屏幕的坐标,getx是相对于按钮的坐标
   wmparams.x = (int) event.getrawx()
    - mfloatview.getmeasuredwidth() / 2;
   // 减25为状态栏的高度
   wmparams.y = (int) event.getrawy()
    - mfloatview.getmeasuredheight() / 2 - 75;
   // 刷新
   mwindowmanager.updateviewlayout(mfloatlayout, wmparams);
   return true;
  case motionevent.action_up:
   mfloatview.setbackgroundresource(r.drawable.circle_cyan);
   return isclick;// 此处返回false则属于移动事件,返回true则释放事件,可以出发点击否。
  default:
   break;
  }
  return false;
  }
    });  
    mfloatview.setonclicklistener(new onclicklistener()  
    { 
      @override 
      public void onclick(view v)  
      { 
        toast.maketext(floatviewservice.this, "一百块都不给我!", toast.length_short).show(); 
      } 
    }); 
  } 
  @override 
  public void ondestroy()  
  { 
    super.ondestroy(); 
    if(mfloatlayout != null) 
    { 
      //移除悬浮窗口 
      mwindowmanager.removeview(mfloatlayout); 
    } 
  }
 @override
 public ibinder onbind(intent intent) {
 return null;
 } 
}

悬浮窗的xml文件

alert_window_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="vertical" >
  <imagebutton
    android:id="@+id/alert_window_imagebtn" 
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@drawable/float_window_menu"
    android:contentdescription="@null"
    />
</linearlayout>

以上内容是实现android 全界面悬浮按钮的全部叙述,希望大家喜欢。

上一篇:

下一篇: