Android自定义浮框,Android实现全局悬浮框

本文详细介绍了如何在Android中实现全局悬浮窗,包括在AndroidManifest.xml中添加权限,自定义悬浮窗类,以及处理触摸事件来实现悬浮窗的移动和隐藏。代码示例展示了从创建到显示、更新和隐藏悬浮窗的全过程。同时,文中还提供了检查和请求系统权限的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实例为大家分享了android实现全局悬浮框的具体代码,供大家参考,具体内容如下

效果图:

7d86b83cb4a9e39ff2fe2bc19b4188c6.png

代码实现:

androidmanifest.xml添加弹框权限

自定义悬浮窗类floatwindow.java

public class floatwindow implements view.ontouchlistener {

private context mcontext;

private windowmanager.layoutparams mwindowparams;

private windowmanager mwindowmanager;

private view mfloatlayout;

private float minviewx;

private float minviewy;

private float mdowninscreenx;

private float mdowninscreeny;

private float minscreenx;

private float minscreeny;

private textview infotext;

public floatwindow(context context) {

this.mcontext = context;

initfloatwindow();

}

private void initfloatwindow() {

layoutinflater inflater = layoutinflater.from(mcontext);

if(inflater == null)

return;

mfloatlayout = (view) inflater.inflate(r.layout.layout_float, null);

infotext = mfloatlayout.findviewbyid(r.id.textview);

mfloatlayout.setontouchlistener(this);

mwindowparams = new windowmanager.layoutparams();

mwindowmanager = (windowmanager) mcontext.getsystemservice(context.window_service);

if (build.version.sdk_int >= 26) {//8.0新特性

mwindowparams.type = windowmanager.layoutparams.type_application_overlay;

}else{

mwindowparams.type = windowmanager.layoutparams.type_system_alert;

}

mwindowparams.format = pixelformat.rgba_8888;

mwindowparams.flags = windowmanager.layoutparams.flag_not_focusable;

mwindowparams.gravity = gravity.start | gravity.top;

mwindowparams.width = windowmanager.layoutparams.wrap_content;

mwindowparams.height = windowmanager.layoutparams.wrap_content;

}

@override

public boolean ontouch(view view, motionevent motionevent) {

return floatlayouttouch(motionevent);

}

private boolean floatlayouttouch(motionevent motionevent) {

switch (motionevent.getaction()) {

case motionevent.action_down:

// 获取相对view的坐标,即以此view左上角为原点

minviewx = motionevent.getx();

minviewy = motionevent.gety();

// 获取相对屏幕的坐标,即以屏幕左上角为原点

mdowninscreenx = motionevent.getrawx();

mdowninscreeny = motionevent.getrawy() - getsysbarheight(mcontext);

minscreenx = motionevent.getrawx();

minscreeny = motionevent.getrawy() - getsysbarheight(mcontext);

break;

case motionevent.action_move:

// 更新浮动窗口位置参数

minscreenx = motionevent.getrawx();

minscreeny = motionevent.getrawy() - getsysbarheight(mcontext);

mwindowparams.x = (int) (minscreenx- minviewx);

mwindowparams.y = (int) (minscreeny - minviewy);

// 手指移动的时候更新小悬浮窗的位置

mwindowmanager.updateviewlayout(mfloatlayout, mwindowparams);

break;

case motionevent.action_up:

// 如果手指离开屏幕时,xdowninscreen和xinscreen相等,且ydowninscreen和yinscreen相等,则视为触发了单击事件。

if (mdowninscreenx == minscreenx && mdowninscreeny == minscreeny){

}

break;

}

return true;

}

public void showfloatwindow(){

if (mfloatlayout.getparent() == null){

displaymetrics metrics = new displaymetrics();

// 默认固定位置,靠屏幕右边缘的中间

mwindowmanager.getdefaultdisplay().getmetrics(metrics);

mwindowparams.x = metrics.widthpixels;

mwindowparams.y = metrics.heightpixels/2 - getsysbarheight(mcontext);

mwindowmanager.addview(mfloatlayout, mwindowparams);

}

}

public void updatetext(final string s) {

infotext.settext(s);

}

public void hidefloatwindow(){

if (mfloatlayout.getparent() != null)

mwindowmanager.removeview(mfloatlayout);

}

public void setfloatlayoutalpha(boolean alpha){

if (alpha)

mfloatlayout.setalpha((float) 0.5);

else

mfloatlayout.setalpha(1);

}

// 获取系统状态栏高度

public static int getsysbarheight(context contex) {

class> c;

object obj;

field field;

int x;

int sbar = 0;

try {

c = class.forname("com.android.internal.r$dimen");

obj = c.newinstance();

field = c.getfield("status_bar_height");

x = integer.parseint(field.get(obj).tostring());

sbar = contex.getresources().getdimensionpixelsize(x);

} catch (exception e1) {

e1.printstacktrace();

}

return sbar;

}

}

自定义悬浮窗界面布局文件layout_float.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/imageview"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@mipmap/float_win"

app:layout_constraintstart_tostartof="parent"

app:layout_constrainttop_totopof="parent"/>

android:id="@+id/textview"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="#00ffffff"

android:text="hello"

android:textsize="12sp"

app:layout_constraintleft_toleftof="@id/imageview"

app:layout_constraintright_torightof="@id/imageview"

app:layout_constrainttop_tobottomof="@id/imageview"/>

在activity中使用悬浮窗。

public class mainactivity extends appcompatactivity {

private button btnshow;

floatwindow floatwindow;

@override

protected void oncreate(bundle savedinstancestate) {

super.oncreate(savedinstancestate);

// 权限判断

if (build.version.sdk_int >= 23) {

if(!settings.candrawoverlays(getapplicationcontext())) {

// 启动activity让用户授权

intent intent = new intent(settings.action_manage_overlay_permission,uri.parse("package:" + getpackagename()));

startactivityforresult(intent,10);

} else {

// 执行6.0以上绘制代码

initview();

}

} else {

// 执行6.0以下绘制代码

initview();

}

}

@override

protected void onresume() {

super.onresume();

// 权限判断

if (build.version.sdk_int >= 23) {

if(settings.candrawoverlays(getapplicationcontext())) {

initview();

}

} else {

//执行6.0以下绘制代码

initview();

}

}

private void initview() {

setcontentview(r.layout.activity_main);

floatwindow = new floatwindow(getapplicationcontext());

btnshow = findviewbyid(r.id.btn_show);

btnshow.setonclicklistener(new view.onclicklistener() {

@override

public void onclick(view view) {

if (null != floatwindow) {

floatwindow.showfloatwindow();

}

}

});

button btnrefresh = findviewbyid(r.id.btn_refresh);

btnrefresh.setonclicklistener(new view.onclicklistener() {

@override

public void onclick(view view) {

int random = (int) (math.random() * 10);

if (null != floatwindow) {

floatwindow.updatetext(string.valueof(random));

}

}

});

}

@override

protected void ondestroy() {

super.ondestroy();

if (null != floatwindow) {

floatwindow.hidefloatwindow();

}

}

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值