Android 全界面悬浮按钮实现,you can do it!

最近工作原因,没有及时更新博客。各位看官原谅则个。

我们每天都这样周而复始的工作,生活,生活,工作。就像头两天看到空间好友里,小源同学的一句话“人与人的不同在于:你是真的活了一万多天,还是仅仅生活了一天,却重复了一万多次。”

我们都像生活的有资有色,当年迈的时候,回首往事,可以每次都跟爱人、亲人、友人会议那么多的精彩往事,而不是每次都重复一个自认为精彩的故事。

努力吧,骚年。为了曾经吹过的牛B。

正文

开始我以为悬浮窗口,,可以用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 {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onStart() { Intent intent = new Intent(MainActivity.this, FloatViewService.class);//启动FloatViewServicestartService(intent);super.onStart();}@Overrideprotected void onStop() {// 销毁悬浮窗Intent intent = new Intent(MainActivity.this, FloatViewService.class);//终止FloatViewServicestopService(intent);super.onStop();}}

activity_main.xml

<RelativeLayout xmlns:android=""xmlns: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" ><TextViewandroid: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;@Overridepublic void onCreate(){super.onCreate();Log.i(TAG, "onCreate");createFloatView();}@SuppressWarnings("static-access")@SuppressLint("InflateParams") private void createFloatView(){wmParams = new WindowManager.LayoutParams();//通过getApplication获取的是WindowManagerImpl.CompatModeWrappermWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE);//设置window typewmParams.type = LayoutParams.TYPE_PHONE;//设置图片格式,效果为背景透明wmParams.format = PixelFormat.RGBA_8888;//设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE;//调整悬浮窗显示的停靠位置为左侧置顶wmParams.gravity = Gravity.LEFT | Gravity.TOP;// 以屏幕左上角为原点,设置x、y初始值,相对于gravitywmParams.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);//添加mFloatLayoutmWindowManager.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") @Overridepublic 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(){@Overridepublic void onClick(View v){Toast.makeText(FloatViewService.this, "一百块都不给我!", Toast.LENGTH_SHORT).show();}});}@Overridepublic void onDestroy(){super.onDestroy();if(mFloatLayout != null){//移除悬浮窗口mWindowManager.removeView(mFloatLayout);}}@Overridepublic IBinder onBind(Intent intent) {return null;}} 悬浮窗的xml文件

alert_window_menu.xml

人生的小河,总要流过森林,荒漠,

Android 全界面悬浮按钮实现,you can do it!

相关文章:

你感兴趣的文章:

标签云: