悬浮窗口怎么设置

更新时间:2023-03-08 12:39:42 阅读: 评论:0

大学生恋爱-jaybird

悬浮窗口怎么设置
2023年3月8日发(作者:会计找工作)

android⾃动悬浮窗代码,Android实现桌⾯悬浮窗、蒙板效果实

例代码

现在很多安全类的软件,⽐如360⼿机助⼿,百度⼿机助⼿等等,都有⼀个悬浮窗,可以飘浮在桌⾯上,⽅便⽤户使⽤⼀些常⽤的操作。

今天这篇⽂章,就是介绍如何实现桌⾯悬浮窗效果的。

⾸先,看⼀下效果图。

悬浮窗⼀共分为两个部分,⼀个是平常显⽰的⼩窗⼝,另外⼀个是点击⼩窗⼝显⽰出来的⼆级悬浮窗⼝。

⾸先,先看⼀下这个项⽬的⽬录结构。

最关键的就是红框内的四个类。

⾸先,FloatWindowService是⼀个后台的服务类,主要负责在后台不断的刷新桌⾯上的⼩悬浮窗⼝,否则会导致更换界⾯之后,悬浮窗⼝

也会随之消失,因此需要不断的刷新。下⾯是实现代码。

indow;

;

ask;

e;

t;

;

r;

r;

/**

*悬浮窗后台服务

*

*@authorzhaokaiqiang

*

*/

publicclassFloatWindowServiceextendsService{

publicstaticfinalStringLAYOUT_RES_ID="layoutResId";

publicstaticfinalStringROOT_LAYOUT_ID="rootLayoutId";

//⽤于在线程中创建/移除/更新悬浮窗

privateHandlerhandler=newHandler();

privateContextcontext;

privateTimertimer;

//⼩窗⼝布局资源id

privateintlayoutResId;

//布局根布局id

privateintrootLayoutId;

@Override

publicintonStartCommand(Intentintent,intflags,intstartId){

context=this;

layoutResId=Extra(LAYOUT_RES_ID,0);

rootLayoutId=Extra(ROOT_LAYOUT_ID,0);

if(layoutResId==0||rootLayoutId==0){

thrownewIllegalArgumentException(

"layoutResIdorrootLayoutIdisillegal");

}

if(timer==null){

timer=newTimer();

//每500毫秒就执⾏⼀次刷新任务

leAtFixedRate(newRefreshTask(),0,500);

}

tCommand(intent,flags,startId);

}

@Override

publicvoidonDestroy(){

roy();

//Service被终⽌的同时也停⽌定时器继续运⾏

();

timer=null;

}

privateclassRefreshTaskextendsTimerTask{

@Override

publicvoidrun(){

//当前界⾯没有悬浮窗显⽰,则创建悬浮

if(!tance(context).isWindowShowing()){

(newRunnable(){

@Override

publicvoidrun(){

tance(context)

.createSmallWindow(context,layoutResId,

rootLayoutId);

}

});

}

}

}

@Override

publicIBinderonBind(Intentintent){

returnnull;

}

}

除了后台服务之外,我们还需要两个⾃定义的布局,分别是FloatWindowSmallView和FloatWindowBigView,这两个⾃定义的布局,主

要负责悬浮窗的前台显⽰,我们分别看⼀下代码实现。

⾸先是FloatWindowSmallView类的实现。

indow;

;

ssLint;

t;

ormat;

y;

Inflater;

Event;

;

Manager;

Layout;

ew;

Utils;

ngwindow.R;

/**

*⼩悬浮窗,⽤于初始显⽰

*

*@authorzhaokaiqiang

*

*/

publicclassFloatWindowSmallViewextendsLinearLayout{

//⼩悬浮窗的宽

publicintviewWidth;

//⼩悬浮窗的⾼

publicintviewHeight;

//系统状态栏的⾼度

privatestaticintstatusBarHeight;

//⽤于更新⼩悬浮窗的位置

privateWindowManagerwindowManager;

//⼩悬浮窗的布局参数

ParamssmallWindowParams;

//记录当前⼿指位置在屏幕上的横坐标

privatefloatxInScreen;

//记录当前⼿指位置在屏幕上的纵坐标

privatefloatyInScreen;

//记录⼿指按下时在屏幕上的横坐标,⽤来判断单击事件

privatefloatxDownInScreen;

//记录⼿指按下时在屏幕上的纵坐标,⽤来判断单击事件

privatefloatyDownInScreen;

//记录⼿指按下时在⼩悬浮窗的View上的横坐标

privatefloatxInView;

//记录⼿指按下时在⼩悬浮窗的View上的纵坐标

privatefloatyInView;

//单击接⼝

privateOnClickListenerlistener;

/**

*构造函数

*

*@paramcontext

*上下⽂对象

*@paramlayoutResId

*布局资源id

*@paramrootLayoutId

*根布局id

*/

publicFloatWindowSmallView(Contextcontext,intlayoutResId,

introotLayoutId){

super(context);

windowManager=(WindowManager)context

.getSystemService(_SERVICE);

(context).inflate(layoutResId,this);

Viewview=findViewById(rootLayoutId);

viewWidth=outParams().width;

viewHeight=outParams().height;

statusBarHeight=getStatusBarHeight();

TextViewpercentView=(TextView)findViewById(t);

t("悬浮窗");

smallWindowParams=Params();

//设置显⽰类型为phone

=_PHONE;

//显⽰图⽚格式

=_8888;

//设置交互模式

=_NOT_TOUCH_MODAL

|_NOT_FOCUSABLE;

//设置对齐⽅式为左上

y=|;

=viewWidth;

=viewHeight;

smallWindowParams.x=eenWidth(context);

smallWindowParams.y=eenHeight(context)/2;

}

@SuppressLint("ClickableViewAccessibility")

@Override

publicbooleanonTouchEvent(MotionEventevent){

switch(ion()){

//⼿指按下时记录必要的数据,纵坐标的值都减去状态栏的⾼度

_DOWN:

//获取相对与⼩悬浮窗的坐标

xInView=();

yInView=();

//按下时的坐标位置,只记录⼀次

xDownInScreen=X();

yDownInScreen=Y()-statusBarHeight;

break;

_MOVE:

//时时的更新当前⼿指在屏幕上的位置

xInScreen=X();

yInScreen=Y()-statusBarHeight;

//⼿指移动的时候更新⼩悬浮窗的位置

updateViewPosition();

break;

_UP:

//如果⼿指离开屏幕时,按下坐标与当前坐标相等,则视为触发了单击事件

if(xDownInScreen==X()

&&yDownInScreen==(Y()-getStatusBarHeight())){

if(listener!=null){

();

}

}

break;

}

returntrue;

}

/**

*设置单击事件的回调接⼝

*/

publicvoidtOnClickListener(OnClickListenerlistener){

er=listener;

}

/**

*更新⼩悬浮窗在屏幕中的位置

*/

privatevoidupdateViewPosition(){

smallWindowParams.x=(int)(xInScreen-xInView);

smallWindowParams.y=(int)(yInScreen-yInView);

ViewLayout(this,smallWindowParams);

}

/**

*获取状态栏的⾼度

*

*@return

*/

privateintgetStatusBarHeight(){

try{

Class>c=e("al.R$dimen");

Objecto=tance();

Fieldfield=ld("status_bar_height");

intx=(Integer)(o);

returngetResources().getDimensionPixelSize(x);

}catch(Exceptione){

tackTrace();

}

return0;

}

/**

*单击接⼝

*

*@authorzhaokaiqiang

*

*/

publicinterfaceOnClickListener{

publicvoidclick();

}

}

在这个类⾥⾯,主要的⼯作是实现悬浮窗⼝在桌⾯前端的实现,还有就是位置的移动和单击事件的判断以及处理。这⾥使⽤的是主要是

WindowManager类的⼀些⽅法和属性,下⼀篇会详细说明,这篇只说实现。

除了⼩悬浮窗之外,点击之后弹出的⼆级悬浮窗也是类似的⽅式添加到桌⾯上,下⾯是⼆级悬浮窗的代码。

indow;

t;

ormat;

y;

Inflater;

;

Manager;

Layout;

ew;

Utils;

ngwindow.R;

publicclassFloatWindowBigViewextendsLinearLayout{

//记录⼤悬浮窗的宽

publicintviewWidth;

//记录⼤悬浮窗的⾼

publicintviewHeight;

ParamsbigWindowParams;

privateContextcontext;

publicFloatWindowBigView(Contextcontext){

super(context);

t=context;

(context).inflate(_window_big,this);

Viewview=findViewById(_window_layout);

viewWidth=outParams().width;

viewHeight=outParams().height;

bigWindowParams=Params();

//设置显⽰的位置,默认的是屏幕中⼼

bigWindowParams.x=eenWidth(context)/2-viewWidth

/2;

bigWindowParams.y=eenHeight(context)/2

-viewHeight/2;

=_PHONE;

=_8888;

//设置交互模式

=_NOT_TOUCH_MODAL

|_NOT_FOCUSABLE;

y=|;

=viewWidth;

=viewHeight;

initView();

}

privatevoidinitView(){

TextViewtv_back=(TextView)findViewById(_back);

tv_lickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

tance(context).removeBigWindow();

}

});

}

}

这些基本的类建⽴起来之后,剩下的就是最重要的类FloatWindowManager的实现。这个类实现的就是对悬浮窗的操作。

indow;

t;

;

Manager;

/**

*悬浮窗管理器

*

*@authorzhaokaiqiang

*

*/

publicclassFloatWindowManager{

//⼩悬浮窗对象

privateFloatWindowSmallViewsmallWindow;

//⼤悬浮窗对象

privateFloatWindowBigViewbigWindow;

//⽤于控制在屏幕上添加或移除悬浮窗

privateWindowManagermWindowManager;

//FloatWindowManager的单例

privatestaticFloatWindowManagerfloatWindowManager;

//上下⽂对象

privateContextcontext;

privateFloatWindowManager(Contextcontext){

t=context;

}

publicstaticFloatWindowManagergetInstance(Contextcontext){

if(floatWindowManager==null){

floatWindowManager=newFloatWindowManager(context);

}

returnfloatWindowManager;

}

/**

*创建⼩悬浮窗

*

*@paramcontext

*必须为应⽤程序的Context.

*/

publicvoidcreateSmallWindow(Contextcontext,intlayoutResId,

introotLayoutId){

WindowManagerwindowManager=getWindowManager();

if(smallWindow==null){

smallWindow=newFloatWindowSmallView(context,layoutResId,

rootLayoutId);

w(smallWindow,indowParams);

}

}

/**

*将⼩悬浮窗从屏幕上移除

*

*@paramcontext

*/

publicvoidremoveSmallWindow(){

if(smallWindow!=null){

WindowManagerwindowManager=getWindowManager();

View(smallWindow);

smallWindow=null;

}

}

publicvoidtOnClickListener(kListenerlistener){

if(smallWindow!=null){

lickListener(listener);

}

}

/**

*创建⼤悬浮窗

*

*@paramcontext

*必须为应⽤程序的Context.

*/

publicvoidcreateBigWindow(Contextcontext){

WindowManagerwindowManager=getWindowManager();

if(bigWindow==null){

bigWindow=newFloatWindowBigView(context);

w(bigWindow,dowParams);

}

}

/**

*将⼤悬浮窗从屏幕上移除

*

*@paramcontext

*/

publicvoidremoveBigWindow(){

if(bigWindow!=null){

WindowManagerwindowManager=getWindowManager();

View(bigWindow);

bigWindow=null;

}

}

publicvoidremoveAll(){

rvice(newIntent(context,));

removeSmallWindow();

removeBigWindow();

}

/**

*是否有悬浮窗显⽰(包括⼩悬浮窗和⼤悬浮)

*

*@return有悬浮窗显⽰在桌⾯上返回true,没有的话返回fal

*/

publicbooleanisWindowShowing(){

returnsmallWindow!=null||bigWindow!=null;

}

/**

*如果WindowManager还未创建,则创建新的WindowManager返回。否则返回当前已创建的WindowManager

*

*@paramcontext

*@return

*/

privateWindowManagergetWindowManager(){

if(mWindowManager==null){

mWindowManager=(WindowManager)context

.getSystemService(_SERVICE);

}

returnmWindowManager;

}

}

还有个获取屏幕宽⾼的帮助类。

;

t;

Manager;

/**

*屏幕帮助类

*

*@authorzhaokaiqiang

*

*/

publicclassScreenUtils{

/**

*获取屏幕宽度

*

*@return

*/

@SuppressWarnings("deprecation")

publicstaticintgetScreenWidth(Contextcontext){

return((WindowManager)context

.getSystemService(_SERVICE)).getDefaultDisplay()

.getWidth();

}

/**

*获取屏幕宽度

*

*@return

*/

@SuppressWarnings("deprecation")

publicstaticintgetScreenHeight(Contextcontext){

return((WindowManager)context

.getSystemService(_SERVICE)).getDefaultDisplay()

.getHeight();

}

}

完成这些,我们就可以直接⽤了。

;

ty;

t;

;

;

nt;

;

ngwindow.R;

indowManager;

indowService;

kListener;

/**

*⽰例

*

*@ClassName:tivity

*@Description:

*@authorzhaokaiqiang

*@date2014-10-23下午11:30:13

*

*/

publicclassMainActivityextendsActivity{

privateFloatWindowManagerfloatWindowManager;

privateContextcontext;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

te(savedInstanceState);

tContentView(ty_main);

context=this;

floatWindowManager=tance(context);

}

/**

*显⽰⼩窗⼝

*

*@paramview

*/

publicvoidshow(Viewview){

//需要传递⼩悬浮窗布局,以及根布局的id,启动后台服务

Intentintent=newIntent(context,);

ra(_RES_ID,

_window_small);

ra(_LAYOUT_ID,

_window_layout);

startService(intent);

}

/**

*显⽰⼆级悬浮窗

*

*@paramview

*/

publicvoidshowBig(Viewview){

//设置⼩悬浮窗的单击事件

lickListener(newOnClickListener(){

@Override

publicvoidclick(){

BigWindow(context);

}

});

}

/**

*移除所有的悬浮窗

*

*@paramview

*/

publicvoidremove(Viewview){

All();

}

@Override

publicbooleanonKeyDown(intkeyCode,KeyEventevent){

//返回键移除⼆级悬浮窗

if(keyCode==E_BACK

&&ion()==_DOWN){

BigWindow();

returntrue;

}

own(keyCode,event);

}

}

在上⾯⽂章中,我们介绍了如何实现桌⾯悬浮窗⼝,在这个效果的实现过程中,最重要的⼀个类就是WindowManager,今天这篇⽂章,将

对WindowManager的使⽤进⾏介绍,并且实现⼀个使⽤WindowManager来实现⽤户打开APP,显⽰⾸次使⽤教学蒙板的效果。

WindowManager类实现了ViewManager接⼝,ViewManager接⼝允许我们在Activity上添加或者是移除view,因此WindowManager

也允许我们在Activity上进⾏View的添加和移除操作。

我们可以通过下⾯的⽅法获取⼀个WindowManager对象

temService(_SERVICE)

在Activity之中,我们可以直接通过getWindowManager()获取到⼀个WindowManager对象。

每⼀个WindowManager实例都被绑定到⼀个独有的Display对象上⾯,如果我们想获取不同Display的WindowManager对象,我们可以

通过createDisplayContext(Display)获取到这个Display的Context对象,然后使⽤上⾯的⽅法,也可以获取到⼀个WindowManager对

象。

我们在使⽤WindowManager类的时候,通常使⽤下⾯的⼏个⽅法:

w(View,Param);

View();

aultDisplay();

w()⽅法⽤来向当前的窗⼝上添加View对象,需要接受两个参数,View是要添加到窗⼝的View对象,⽽

Param则是添加的窗⼝的参数,在上⼀篇添加悬浮窗的操作的时候,需要对LayoutParam设置很多参数,下⾯

我们看⼀下常⽤的设置

//设置LayoutParams参数

LayoutParamsparams=Params();

//设置显⽰的类型,TYPE_PHONE指的是来电话的时候会被覆盖,其他时候会在最前端,显⽰位置在stateBar下⾯,其他更多的值请查阅

⽂档

=_PHONE;

//设置显⽰格式

=_8888;

//设置对齐⽅式

y=|;

//设置宽⾼

=eenWidth(this);

=eenHeight(this);

//设置显⽰的位置

params.x;

params.y;

设置好LayoutParam之后,我们就可以通过w(View,Param)将View添加到窗⼝之

上,不过,我们需要申明权限

添加完成之后,我们就可以在窗⼝上看到我们添加的View对象了。如果我们想将添加的View移除,我们只需要调⽤

View()即可,参数就是我们前⾯使⽤的View对象,使⽤很简单。除了这个⽅法,还有个

ViewImmediate(),也可以将View移除,但是⽂档中说,这个⽅法并不是给⼀般程序调⽤的,因此需要⼩⼼使

⽤,我们开发的都属于⼀般程序,建议不要使⽤这个⽅法。

除了这两个⽅法之外,我们最常⽤的另外⼀个⽅法就是aultDisplay(),通过这个⽅法,我们可以获取到当前界⾯

的Display的⼀个对象,然后我们就可以获取到当前屏幕的⼀些参数,⽐如说宽⾼。

下⾯是我常⽤的⼀个⼯具类。

ask;

t;

Manager;

/**

*屏幕帮助类

*

*@authorzhaokaiqiang

*

*/

publicclassScreenUtils{

/**

*获取屏幕宽度

*

*@return

*/

@SuppressWarnings("deprecation")

publicstaticintgetScreenWidth(Contextcontext){

return((WindowManager)context

.getSystemService(_SERVICE)).getDefaultDisplay()

.getWidth();

}

/**

*获取屏幕宽度

*

*@return

*/

@SuppressWarnings("deprecation")

publicstaticintgetScreenHeight(Contextcontext){

return((WindowManager)context

.getSystemService(_SERVICE)).getDefaultDisplay()

.getHeight();

}

}

知道上⾯这些之后,我们就可以实现教学模板效果了,⾸先看效果图。

下⾯是代码实现

ask;

ty;

ormat;

;

y;

;

kListener;

Manager;

Params;

iew;

ype;

publicclassMainActivityextendsActivity{

privateImageViewimg;

privateWindowManagerwindowManager;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

te(savedInstanceState);

tContentView(ty_main);

windowManager=getWindowManager();

//动态初始化图层

img=newImageView(this);

outParams(newLayoutParams(

_PARENT,

_PARENT));

leType(_XY);

geResource();

//设置LayoutParams参数

LayoutParamsparams=Params();

//设置显⽰的类型,TYPE_PHONE指的是来电话的时候会被覆盖,其他时候会在最前端,显⽰位置在stateBar下⾯,其他更多的值请查阅

⽂档

=_PHONE;

//设置显⽰格式

=_8888;

//设置对齐⽅式

y=|;

//设置宽⾼

=eenWidth(this);

=eenHeight(this);

//添加到当前的窗⼝上

w(img,params);

//点击图层之后,将图层移除

lickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewarg0){

View(img);

}

});

}

}

以上所述是⼩编给⼤家介绍的Android实现桌⾯悬浮窗、蒙板效果实例代码,希望对⼤家有所帮助!

本文发布于:2023-03-08 12:39:41,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/1678250382183805.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:悬浮窗口怎么设置.doc

本文 PDF 下载地址:悬浮窗口怎么设置.pdf

上一篇:无人机拍摄
下一篇:返回列表
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 站长QQ:55-9-10-26 专利检索|