首页 > 系统 > Android > 正文

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

2020-04-11 11:07:50
字体:
来源:转载
供稿:网友

开始我以为悬浮窗口,可以用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.javapackage 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 全界面悬浮按钮的全部叙述,希望大家喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表